What is a Search? | Yext Hitchhikers Platform
It’s important to understand which user actions constitute a “search” in Yext for a couple of key reasons:
- Pricing: You pay per search, so you should know what counts as one
- Analytics: If you don’t know what counts as a search, it’ll be hard to make sense of the data
Placing and executing a query in the search bar may be the most obvious search “action”, but there are actually many more ways to place a search in a Yext Search experience! This document will walk you through what is and what is not considered a search. At a high level, this is the breakdown:
What is a Search
- Placing a Search (universal and vertical)
- Blank Searches
- Navigating Between Tabs (Most of the Time)
- Selecting a Facet
- Selecting a Static Filter
- Sorting Results
What is not a Search
- Filter Search
- Visual Autocomplete and Debouncing
What is a Search
Every time a search is placed, it generates a unique query ID. Any subsequent non-search actions do not generate a new query ID. Once a search action is triggered, a new unique query ID is created, and so on.
Thus, a good rule of thumb for determining whether an action qualifies as a search is whether a new query ID was generated. You can even check this for yourself by inspecting the page, clicking the ‘Network’ tab and refreshing the search (below).
Each item under ‘Name’ is a request - click on the request starting with “query” (or filter for “query”) to open up the API response and look for requests to ‘cdn.yextapis.com’.
Double click the request to open the full API request in a new tab, which will include the query ID!
Placing a Search
Placing a search in either the universal (main) or any of the vertical tabs of the search experience is considered a search. If a user has already placed a universal search or vertical search, this will generate a new query ID and be treated as a new search.
Even blank queries count as a search if you set
allowEmptySearch to true (see Blank Searches below).
For both universal and vertical searches, if the page automatically triggers a search on load, this still counts as a search. For example, if the user clicks on a link to a query, that action will run a search for that query.
With both universal and vertical search, there are certain situations when a blank query counts as a search, so if the user presses enter without entering a search query, a search is fired. This behavior is determined by the
in the frontend. Blank searches are only possible if the user sets
allowEmptySearch to True for that vertical or universal config.
When a user sets
allowEmptySearch to True, a blank query counts as a search:
- For vertical search and all results for that vertical are returned.
- When a . Otherwise, a blank search on universal will not fire.
- When users clear an existing query with the search bar clear button (or by manually clearing the search bar and hitting Enter).
allowEmptySearch is set to False, no search is fired and no results are returned until a user inputs a non-blank query and runs a search. In this case, clearing the search bar will NOT run a blank search.
Navigating Between Tabs (Most of the Time)
In the vast majority of cases, simply clicking on a new tab will also count as a search. This applies when switching between verticals, from universal to vertical, and vice versa.
In the below example, when we navigate from the Platform tab to the Customers tab with the query ‘search’ already populated, a new search is automatically triggered for the existing query ‘search’ in the Customers tab. Although no new query is specified, a search is fired using the existing query, in the new tab. This is also the case with blank queries, as long as
allowEmptySearch is set to True.
Selecting a Facet
For the uninitiated, facets are a type of filter that are generated server-side (post-search), that allow a searcher to filter results to their liking based on their specific query. See the unit for a deeper-dive.
Facets can be applied in two ways. The first is by including a facet value in the query. When we search ‘Search’, the facet is automatically applied and the facet box in the left navigation is checked. Depending on how the facet is configured (more on this later), unchecking the facet box can remove the facet from the results.
The other way to apply a facet is to directly check or uncheck the box next to the facet name in the left navigation.
With (un)checking the facet boxes, there are two (2) possible behaviors. These behaviors depend on how you configure the
when setting up the facets. As the name suggests,
searchOnChange determines whether a new search is fired whenever a facet selection changes.
searchOnChange is set to True, a new search is fired whenever a facet is selected or unselected. If it is set to False, the user must first make their facet selections, then click on an ‘Apply’ button generated by the configuration for a search to be executed.
In either case, searches are counted. It’s just a matter of when in the process they’re counted (immediately when facet boxes are checked/unchecked or only when the user clicks ‘Apply’) and how many searches are counted (each time a facet box is checked/unchecked or only once when the user clicks ‘Apply’ with potentially multiple facets added to the same search).
Selecting a Static Filter
Unlike facets, static filters are generated on the client-side, meaning they are pre-configured on the front-end and passed into the Search API. This also means static filters appear independently of the content of a user query. When a user queries an experience, any enabled static filter is submitted as an additional filter with the query.
Similarly to facets, static filters have two (2) possible behaviors controlled by the
when setting up the facets.
searchOnChange behaves the same as it does for facets, so when it is set to True, a new search is fired whenever a filter selection changes. If it is set to false, the user must confirm their changes for a search to be run.
If you have
enabled and the
searchOnChange property (which behaves exactly the same as it does for filters and facets) set to True, changing the sort order of your results will automatically run a new search. If it is set to False, you must apply your changes in order for the changes to save - once you do that, a search is executed.
What is Not a Search
Pagination does not count as a standalone search. When a query is executed, the full result set is pulled, but we limit the number of results that show up on page load. A searcher can cycle through all of the results one page at a time by paginating. This preserves the original query ID, which is then passed into subsequent requests as a URL param, so the search is not rerun.
The way Autocomplete works is that each individual keystroke hits our Autocomplete API endpoint (check out our documentation for and ) and returns suggestions that way. Below, you can see that with each keystroke, autocomplete suggestions appear and are dynamically filtered down to match the intent of the query in the search bar.
Some search engines will treat each keystroke as a search, and thus charge per-keystroke. We do not do this. This has major pricing and capacity implications, as the search engines that do this will often accrue approximately 7x more searches (the average length of a query is around seven characters).
At Yext, autocomplete/individual keystrokes are not considered searches, and only treated as such when a) the user selects a suggestion, or b) executes the search on their own. Autocomplete calls are completely free and they do not show up anywhere in our logging or analytics, so you don’t get inundated with keystroke-level data.
Filter Search is basically a set of static filters used in the query to narrow down a result set. Like the Autocomplete API, the gets hit with every single keystroke, and does not charge users on a per-keystroke basis.
However, there are some important distinctions to make between the two. The first is that Filter Search is only available for Vertical Search. The second is that while the Autocomplete API returns a list of queries to the user, the Vertical Search API returns a list of filters.
How can you tell the difference between a query and a filter? Both queries and filters are examples of properties defined by the API. A query is defined by the
, which is a string that contains the search term of a user. So if a user searches for a ‘chicken sandwich’, the
input property of the API response will contain ‘chicken+sandwich’.
filter parameter represents one or more filtering conditions that are applied to the set of entities that would otherwise be returned by the user’s search. For instance, a user could filter results to only show options under 500 calories. The filter would look something like this in the API response:
"$eq": "Under 500 calories"
Once a user has selected their filter(s), they execute a search with their selected filters applied in the
filters parameter of the search. Oftentimes with Filter Search, the
input parameter doesn’t contain anything, but this isn’t always the case - Filter Search and query-based, free-form search are not mutually exclusive.
Special Case: Visual Autocomplete and Debouncing
Visual autocomplete is a special case that technically hits two API endpoints, one of which counts as a search (universal Search) and one of which doesn’t count (autocomplete).
Visual autocomplete is, as the name suggests, autocomplete containing entities and their visual metadata - such as photos - rather than autocomplete containing query suggestions. This is particularly prevalent in e-commerce experiences. See below for an example of what visual autocomplete looks like:
How Does it Work?
How does visual autocomplete work? First, with each keystroke, we hit the Autocomplete API endpoint, which does not count as a search. In addition to hitting the Autocomplete endpoint, we also need to hit the Universal Search API to generate the entity previews.
We achieve this using a practice called , which is used in web browsers to maintain good browser performance by preventing time-consuming tasks from firing too often. In Search, debouncing determines how often a request is made to the Universal endpoint to fetch the entities to preview. Debouncing is user-configurable when implementing the search bar and defaults to 500 milliseconds.
Think of debouncing as a keystroke-based timer with a delay, where a request to the Universal endpoint is only made when the timer has expired in between keystrokes. If two keystrokes are made within 500 milliseconds (or whatever the delay is set to) of each other, the timer will reset to 0 and no call is made to the Universal endpoint. If the delay time expires in between keystrokes, a call is made to the Universal endpoint and a search is executed.
How to Implement
Thanks to our new React library, it’s easy to implement visual autocomplete into a Search experience. We have a built-in that will handle the relatively complicated debouncing logic for you, so all you need to do is add and configure the component to your liking and you should be set! For more information on how to implement the built-in component, check out this .
Pricing and Analytics Implications
To summarize, visual autocomplete hits two (2) endpoints: Universal Search and Autocomplete. Autocomplete is called with each keystroke, free of charge.
Since requests are made to the Universal Search endpoint, there are pricing and analytics implications. Like regular autocomplete, you will not be charged on a per-keystroke basis. You will be charged for every call to the Universal Search API. This is a bit harder to quantify, as the number of calls generated depends on a) how you configure debouncing, and b) how fast a searcher types. If you set a lower debouncing timer, or your users are really slow typers, the Universal endpoint is called more often and you’ll be charged more as a result. On average, we estimate that enabling visual autocomplete results in 3-4x more searches, from both a pricing and analytics perspective.