Query rules allows you to modify search results by adding precise rules.
Search Configuration Schema
Within the Search configuration, the rules array defines the configuration settings for query rules. Each item in the array is an object that defines the query rule. Refer to the table below for the available fields. View where rules fits into the configuration in the Search Config Properties - Top Level reference doc.
| Property | Type | Shown in Config UI | Description |
|---|---|---|---|
criteria |
object | Yes | Map of criterion type to value |
actions |
array of objects | Yes | Array of actions |
actionType |
string | Yes | The action type |
name |
string | Yes | (Optional) The display name of the query rule |
See below for the possible options for criteria and actionType and the JSON structure for each.
Top-Level JSON
The JSON below is for demonstrative purposes only to show the structure of the rules object through the top-level properties. Find more detail about each criteria and action option, with sample code snippets, below.
{
"rules": [
{
"criteria": {},
"actions": [
{},
{}
],
"name": "Query Rule 1"
},
{
"criteria": {},
"actions": [
{},
{}
],
"name": "Query Rule 2"
}
],
}
Criteria
The criteria outlines the conditions that need to be met to activate the query rule. All criteria must be met in order for the query rule to trigger. The possible criteria options are listed below:
| Property in UI | Property in JSON | Type | Description |
|---|---|---|---|
| Search Term contains all | searchTermContainsAll |
array of strings | Check for a token match on the search term. If multiple tokens are included, they must all be present in the search term. |
| Search Term starts with | searchTermStartsWith |
string | Check if the search term starts with exactly this phrase. |
| Search Term ends with | searchTermEndsWith |
string | Check if the search term ends with exactly this phrase. |
| Search Term exactly matches | searchTermExactlyMatches |
string | Check if the search term exactly matches this phrase. |
| Search Term matches regex | searchTermMatchesRegex |
regular expression | Check if the search term matches this regular expression. |
| Context contains | contextContainsKey |
string | Check if the context object contains a certain key. This uses JSONPath. |
| Context matches | contextMatches |
object of filters | Check if a property in the context object equals a specific value uses filter syntax. |
| Referrer Page URL Regex | referrerPageURLRegex |
regular expression | Check if the referrer page URL, which is the user’s entry point into the Search experience, matches this regular expression. This will stay consistent during their Search session. |
| Vertical | verticalKeys |
array of strings | Restrict the rule to only one or more verticals. |
| Search Type is | searchTypes |
string | Restrict to just vertical or universal search. The default is all searches. Options are ALL, VERTICAL, or UNIVERSAL. |
Search Term Contains All
Check for a token match on the search term with the criteria searchTermContainsAll. If multiple tokens are included it will make sure they are all present.
For example, the search query “open jobs for executive chef” would trigger the criteria below:
"criteria": {
"searchTermContainsAll": [
"executive chef",
"open jobs"
]
},
Search Term Starts With
Check if the search term starts with exactly this phrase with the criteria searchTermStartsWith.
For example, the criteria below checks to see if the search term starts with “How do I”.
"criteria": {
"searchTermStartsWith": "How do I"
},
Search Term Ends With
Check if the search term ends with exactly this phrase with the criteria searchTermEndsWith.
For example, the criteria below checks to see if the search term ends with the word “test”.
"criteria": {
"searchTermEndsWith": "test",
},
Search Term Exactly Matches
Check if the search term exactly matches this phrase with the criteria searchTermExactlyMatches.
For example, the criteria below checks to see if the search term is exactly “cancel my account”.
"criteria": {
"searchTermExactlyMatches": "cancel my account",
},
Search Term Matches Regex
Check if the search term matches this regular expression with the criteria searchTermMatchesRegex.
For example, the criteria below checks whether the query is a phone number with the format ###-###-####. Notice there are extra \ compared to the regex needed (^\d{3}-\d{3}-\d{4}$) as they are escape symbols to use the \.
"criteria": {
"searchTermMatchesRegex": "^\\d{3}-\\d{3}-\\d{4}$",
},
Context Contains
Check if the context object contains a certain key with the criteria contextContainsKey. This criteria uses JSONPath to do the matching. Learn more about JSONPath here. Learn how to set the context in the Search Integration - Setting Context guide.
For example, let’s say a user has the context below:
{
jobProspect: true,
market: "Mid-Atlantic"
}
The following criteria checks whether the context contains the jobProspect key, i.e. whether the user is a job prospect because otherwise the key would not be set.
"criteria": {
"contextContainsKey": "$.jobProspect"
},
Context Matches
Check if a property in the context object equals a specific value with the criteria contextMatches. This criteria uses the filter syntax. Check out the Entities API documentation for how to construct filters based on fields. Learn how to set the context in the Search Integration - Setting Context guide.
Using the same context above, the following criteria would check that the value of the jobProspect field equals true and the market field equals Mid-Atlantic.
"criteria": {
"contextMatches": {
"$.jobProspect": {
"$eq": true
},
"$.market": {
"$eq": "Mid-Atlantic"
}
}
},
Referrer Page URL Regex
Check if the referrer page URL, which is the user’s entry point into the Search experience, matches this regular expression with the criteria referrerPageURLRegex. This will stay consistent during their Search session.
For example, the criteria below checks to see if the user came from the Yext Help site with the domain “help.yext.com”.
"criteria": {
"referrerPageURLRegex": "^.*help.yext.com.*",
},
Vertical
Restrict the rule to only one or more verticals with the criteria verticalKeys. For example, the criteria below restricts the rule to just the jobs vertical.
"criteria": {
"verticalKeys": [
"jobs"
]
},
Search Type
Restrict to just vertical or universal search with the criteria searchTypes. The default is all searches. Options are ALL, VERTICAL, or UNIVERSAL.
For example, the criteria below restricts to just universal search.
"criteria": {
"searchTypes": "UNIVERSAL",
},
Actions
Actions will be performed in the order specified.
| Property in UI | Property in JSON | Description |
|---|---|---|
| Boost Entities | BOOST_ENTITIES |
Boost entities to the top of the vertical results. Specify individual entities or in bulk using filter syntax. |
| Bury Entities | BURY_ENTITIES |
Bury entities to the bottom of the vertical results. Specify individual entities or in bulk using filter syntax. |
| Return No Results | RETURN_NO_RESULTS |
Return no results for a given vertical. |
| Add Filter | ADD_FILTER |
Add an additional filter to the search results. Uses filter syntax. |
| Boost Verticals | BOOST_VERTICALS |
Boost verticals to the top of the search results page. |
| Bury Verticals | BURY_VERTICALS |
Bury verticals to the bottom of the search results page. |
| Boost Vertical Intent | BOOST_VERTICAL_INTENT |
Adjust the vertical intent of a query. This can be used to boost or bury entire verticals in universal search. Note: This is being rolled out in favor of the Boost and Bury Verticals rules. |
| Return Pinned Result | RETURN_PINNED_RESULT |
Return an exact hardcoded set of results. This will completely override the search algorithm. |
| Use Function | USE_FUNCTION |
Run a Typescript function from a Yext plugin on our servers and forward the return value to the front-end. |
| Return Custom Data | RETURN_CUSTOM_DATA |
Return a static JSON blob that signals to the front-end to trigger an action. |
Boost and Bury Entities
Boost entities to the top of vertical results with the action BOOST_ENTITIES. Bury entities to the bottom of vertical results with the action BURY_ENTITIES.
Both the boost entities action and the bury entities action use the following properties. verticalKey is always required. You can choose to select individual entityIds or use the filter property to specify entities in bulk with filter syntax.
| Property in UI | Property in JSON | Type | Description |
|---|---|---|---|
| Entities | entityIds |
array of strings | An array of entity IDs to boost or bury. |
| Filters | filter |
object of filters | Filter to set of entities using either a saved filter or a Knowledge Graph field using filter syntax. |
| Verticals | verticalKey |
string | The vertical that contains these entities. |
| (not in UI) | forceResults |
boolean | If true, entities that are not in results will be returned if they are boosted. If false, entities will only be boosted if they are in the results. Defaults to true. |
When configuring the action in JSON, the only difference between boosting and burying entities is whether you set the actionType as BOOST_ENTITIES or BURY_ENTITIES.
Boost entities by specifying entities: In the following example, the Menu Items entity with the ID “NEW-BURRITO” is boosted.
"actions": [
{
"actionType": "BOOST_ENTITIES",
"entityIds": [
"NEW-BURRITO"
],
"verticalKey": "menuItems"
}
]
Boost entities by specifying filters: In the following example, the boosted Menu Item entities are referred to in bulk using the saved filter with ID “1234”. Check out the Entities API documentation for how to construct filters based on fields.
"actions": [
{
"actionType": "BOOST_ENTITIES",
"entityIds": [],
"filter": {
"savedFilterId": {
"$eq": "1234"
}
},
"verticalKey": "menuItems"
}
]
Bury entities by specifying entities: In the following example, the Job entity with ID “job-16” is buried.
"actions": [
{
"actionType": "BURY_ENTITIES",
"entityIds": [
"job-16"
],
"verticalKey": "jobs"
}
]
Bury entities by specifying filters: In the following example, the buried Menu Item entities are selected by filtering on whether the custom field c_oldItem is set to true. Check out the Entities API documentation for how to construct filters based on fields.
"actions": [
{
"actionType": "BURY_ENTITIES",
"entityIds": [],
"filter": {
"c_oldItem": {
"$eq": true
}
},
"verticalKey": "menuItems"
}
]
Return No Results
Return no results for a given vertical with action RETURN_NO_RESULTS. Only one property is needed to specify the verticals.
| Property in UI | Property in JSON | Type | Description |
|---|---|---|---|
| Verticals | verticals |
array of strings | The vertical(s) to return no results for. |
In the following example, no results are returned for the Jobs vertical.
"actions": [
{
"actionType": "RETURN_NO_RESULTS",
"verticals": [ "jobs" ]
}
]
Add Filter
Add an additional filter to the search results with action ADD_FILTER. Both properties are required. Check out the Entities API documentation for how to construct filters based on fields.
| Property in UI | Property in JSON | Type | Description |
|---|---|---|---|
| Verticals | verticals | array of strings | The vertical(s) affected by the filter. |
| Filter | filter | object of filters | The filter to apply. Uses filter syntax. |
In the following example, a saved filter is applied to the FAQs, Jobs, and Locations verticals.
"actions": [
"actionType":"ADD_FILTER",
"verticals": [
"faqs",
"jobs",
"locations"
],
"filter": {
"savedFilterId":{
"$eq":"21466424"
}
}
]
Boost and Bury Verticals
Boost verticals to the top of universal search results with the action BOOST_VERTICALS. Bury entities to the bottom of universal search results with the action BURY_VERTICALS.
Both the boost verticals action and the bury verticals action use the following properties only require one property to specify the verticals.
| Property in UI | Property in JSON | Type | Description |
|---|---|---|---|
| Verticals | verticals |
array of strings | The vertical(s) to boost or bury. |
Boost verticals: In the following example, the FAQs and Help Articles verticals are boosted.
"actions": [
{
"actionType": "BOOST_VERTICALS",
"verticals": [
"faqs",
"help_articles"
]
}
]
Bury verticals: In the following example, the Events vertical is buried.
"actions": [
{
"actionType": "BURY_VERTICALS",
"verticals": [
"faqs"
]
}
]
Boost Vertical Intent
Boost vertical intent is our legacy method for boosting and burying verticals in query rules. It is still supported, but may be removed in a future version of Search. Use the “Boost Verticals” and “Bury Verticals” actions instead.
| Property in UI | Property in JSON | Type | Description |
|---|---|---|---|
| Verticals | verticals |
array of strings | The vertical(s) to boost or bury. |
| Boost Value | boostValue |
number | Value between -100 and 100 to bury (negative) or boost (positive) verticals by. |
In the following example, the Events vertical is boosted by a value of 5.
"actions": [
{
"actionType": "BOOST_VERTICAL_INTENT",
"boostValue": 5,
"verticals": [
"events"
]
}
]
Return Pinned Result
Return an exact hardcoded set of results with the action RETURN_PINNED_RESULTS. This will completely override the search algorithm.
For the verticals object, include each an object for each vertical you want in the results. verticalKey is always required. For a Yext vertical, you can choose to select individual entityIds or use the savedFilterId property to specify entities in bulk with a saved filter. For a vertical that is not powered by the Yext platform, it will show the normal results from that backend – you cannot control the order of the results.
| Property in JSON | Type | Description |
|---|---|---|
verticals |
array of objects | Defines the behavior of each vertical included in the pinned results. |
verticalKey |
string | The vertical that contains these entities. |
entityIds |
array of strings | An array of entity IDs to include. |
savedFilterId |
string | The saved filter ID to specify entities in bulk. |
directAnswer |
object | A direct answer that should show alongside the entity results. |
entityId |
string | The entity to pull the direct answer from. |
fieldId |
string | The field from the entity to pull the direct answer from. Note that this fieldId must have direct answers enabled. |
| verticalKey | string | The vertical to pull the direct answer from. |
In the following example, a pinned result is returned with a direct answer from the name field of an entity in the Doctors vertical. The entity results returned are the Specialties vertical using a saved filter, the FAQs vertical with two entities, and the Links vertical.
"actions": [
"actionType": "RETURN_PINNED_RESULT",
"directAnswer": {
"entityId": "230s",
"fieldId": "name",
"verticalKey": "doctors"
},
"verticals": [
{
"verticalKey": "specialties",
"savedFilterId": "21466424"
},
{
"verticalKey": "faqs",
"entityIds": [
"FAQ-1",
"FAQ-2"
]
},
{
"verticalKey": "links"
}
]
]
Use Function
Run a Typescript function from a Yext plugin on our servers and forward the return value to the front-end with the action USE_FUNCTION.
| Property in JSON | Type | Description |
|---|---|---|
plugin |
string | Collections of TypeScript files that are defined as CaC resources in a Yext account. Each plugin has a unique ID and can contain many functions. |
function |
string | The individual TypeScript function that is triggered by this query rule. |
key |
string | Required for any action that returns data in the API response. This is necessary because the front-end needs to know which action the data came from so that it can react appropriately. |
timeout |
number | Optional timeout, defined in milliseconds. If the function invocation takes any longer than this, the request proceeds without it and adds an indication to the API response that the rule has exceeded the timeout. |
async |
boolean | Optional. Set the action as asynchronous, so that nothing is forwarded to the front-end, and the function is not subject to the normal timeout. |
In the example from the guide, we fetch stock prices. If the stock price meets a certain criteria, we want to use the function fetchStockData that we wrote, like so:
"actions": [
{
"actionType": "USE_FUNCTION",
"plugin": "stockDataPlugin",
"function": "fetchStockData",
"key": "stockData",
"timeout": 250,
}
]
If we want to make the function async instead of setting a timeout, it would look like:
"actions": [
{
"actionType": "USE_FUNCTION",
"plugin": "stockDataPlugin",
"function": "fetchStockData",
"key": "stockData",
"async": true,
}
]
Return Custom Data
Return a static JSON blob that signals to the front-end to trigger an action with RETURN_CUSTOM_DATA.
The RETURN_CUSTOM_DATA action is somewhat similar to USE_FUNCTION except it skips the function invocation altogether and just returns some arbitrary JSON to the front-end. This means that we don’t have to worry about errors, timeouts, or asynchronous functions, since we aren’t actually executing any code.
Generally speaking, the JSON data that is returned in these rules will be some indicator that the front-end should perform some action, such as redirecting to another page or fetching from an API on the client-side.
| Property in JSON | Type | Description |
|---|---|---|
key |
string | Required for any action that returns data in the API response. This is necessary because the front-end needs to know which action the data came from so that it can react appropriately. |
customData |
object | |
action |
string | The action for the frontend to implement. |
In the following example, the action is basically informing the front-end that it should fetch and display the package data, but it’s up to the front-end to actually implement the logic.
"actions": [
{
"actionType": "RETURN_CUSTOM_DATA",
"key": "trackingInfo",
"customData": {
"action": "FETCH_PACKAGE_DATA",
}
}
]
Custom Query Rule Examples
String of Numbers
You can target a 5-7 number string via RegEx (Regular expressions). Regular expressions allow you to search for a pattern of characters, and allows more flexibility when you're looking for query matches. In this case, this query rule would surface a specific FAQ when a string of numbers is searched.
"rules": [
{
"criteria": {
"searchTermMatchesRegex": "\\b\\d{5,7}\\b"
},
"actions": [
{
"actionType": "BOOST_ENTITIES",
"entityIds": [
"FAQ-0"
],
"verticalKey": "faqs"
}
]
}
searchTermContainsAll with Multiple Search Terms
When writing query rules to prescribe search behavior, the searchTermContainsAll criteria can be used to trigger a rule when the query contains defined terms. This will do a token match on the search term. If multiple tokens are included, it will make sure they are all present.
For example, the value ["Heart attack","911"] would trigger the rule in the case the query contains both "Heart attack" and "911".
If, instead, you wanted to make the logic "or" (i.e., trigger the rule when at least 1 of the terms is in the query), you could use searchTermMatchesRegex, using | as an OR operator.
For example, putting the criteria below in the JSON of your query rule would trigger the query rule whenever a query contains "Heart attack" OR "911" (note: multiple terms, each separated by the | OR operator, can be added):
"criteria": {
"searchTermMatchesRegex": [ ".*(heart attack|911).*"]
}
The result of this code is that the query rule would now be triggered on searches containing either "Heart attack" or "911". For example, if the action associated with this rule was to boost urgent care locations, this action would be triggered for any of the following example searches:
- "symptoms of a heart attack"
- "when to call 911"
- "should I call 911 if I am having a heart attack"
This can help you avoid having to write multiple query rules that trigger the same action.
Referrer URLs to Filter Location Results
To filter results to only those that pertain to the online location (i.e. website) a user originates from, Query Rules can be used to detect the URL a user searched from, map it to a value of the custom field "Query Rules Location", and filter the result set to only the entities that have that value populated in the custom field.
For example, take someone searching from a page on "location1.com". We will see that a user searched from a page matching this subdomain, map that to the custom field value of "Location 1", and filter the results such that only results with the field "Query Rules Location" containing "Location 1" appear in the results.
Steps:
1. Mapping URLs to the "Query Rules Locations" custom field
- Create a custom field called "Query Rules Location" that has a multi-option selections for each location URL.
- Within each entity type, select which Query Rule location the type falls under within the "Query Rules Location" field.
- Once all of your locations are labeled correctly, also update the Query Rules Location custom field for all FAQs and Services and click on all the location options within the field. Note: This is so that all FAQs and Services will surface in the Search experience for all location pages.
2. Create Saved Search Filters
- In order to filter results in Query Rules based on the location page the user is searching from, we need to create saved search filters for each location page.
- Within the Knowledge Graph, create an advanced filter with the following search criteria:
- Fields with Data includes any of Query Rules Location
- Query Rules Location includes Choose the Location you want to filter for
- Apply filter and save the Filter.
3. Creating Query Rule in Search Configuration
Navigate to the Search Configuration and add the following:
"rules": [
{
"criteria": {
"referrerPageURLRegex": "^.location1.com"
},
"actions": [
{
"actionType":"ADD_FILTER",
"verticals": [
"faqs",
"jobs",
"locations"
],
"filter":{
"savedFilterId":{
"$eq":"21466424"
}
}
}
]
}
]
Pinning Results on Default Initial Search
Note: You must be on Theme v1.20 or above to use default initial search. Check out the Upgrade the Theme and SDK module for more info and the Theme Upgrade guide for step-by-step instructions on upgrading.
The typical user journey is that a user enters a search into a search bar and then lands on the search results page with exactly the answer they're looking for. However, sometimes users land on the search results page before a query has been run. When this happens, they see an empty page.
Now, you can pin results to an empty query to automatically showcase specific results when this happens:
- In your index.json, update the SearchBar component in componentSettings with
"allowEmptySearch": true - In your index.json, add pageSettings to include the default initial search. This should go outside of componentSettings (same place where it is in your verticals).
"pageSettings": {
"search": {
"defaultInitialSearch": "" // Enter a default search term, should be your pinned query
}
},
- Update your Search configuration to include a pinned result. Here's a sample:
{
"criteria": {
"searchTermMatchesRegex": "^$",
"searchTypes": "UNIVERSAL"
},
"actions": [
{
"actionType": "RETURN_PINNED_RESULT",
"verticals": [
{
"savedFilterId": "[[ENTER FILTER ID]]",
"verticalKey": "videos"
},
{
"savedFilterId": "[[ENTER FILTER ID]]",
"verticalKey": "states"
}
]
}
],
"name": "Default Search"
}