The Search API provides personalized, typo-correcting, semantic search for your site. You send this API the search queries users entered, and the API returns the relevant search results tailored to your users’ interests.
Personalized search is a key factor in driving search conversion on many major sites. It is particularly powerful for short search queries (≤ 3 keywords), which account for up to 80% of search traffic in the U.S., but are usually the hardest to get right with traditional search engines. This is because shorter search queries tend to match a larger number of results, but there is not enough information in the query strings alone to determine which results the users are actually looking for.
For example, when users search for jeans on Levi’s.com, it is impossible to know which jeans the user is looking for, among thousands of options. Even if the user adds: jeans for men, it is still unclear to a traditional search engine what style, material, or size the user wants.
In the contrary, with Miso’s personalized search, we not only analyze the search query itself, but also take into account the context in which the searches are made, including who are the users, where are they from, what are their past interactions on the site, what other searches the user made, etc. These signals together allow Miso to generate more than 15% to 20% higher search conversion rate than the traditional non-personalized search engines.
Although personalization is a powerful technique, over-using it can be harmful to the user experiences. In the context of search optimization, the relevancy of the search results are still the most important criteria, and we don’t want personalization to overwhelm the search relevancy. For example, when users search for a very specific term, or directly search for the product names, Miso’s algorithm will respond with the most relevant search results first, and then only apply personalization to rerank more ambiguous search results.
For every search query, you let Miso know the user’s user_id and the search keywords in the API request body,
for example:
POST /v1/search/search
{
"q": "jeans",
"user_id": "user-123"
}
For site visitors who do not sign in, you can let Miso know the anonymous_id of this visitor:
POST /v1/search/search
{
"q": "jeans",
"anonymous_id": "visitor-123"
}
With the query above, Miso responds with the search results like the following:
{
"message":"success",
"data":{
"took":50,
"total":30,
"start":0,
"miso_id":"f34b90de-086b-11eb-b498-1ee8abb1818b",
"products":[
{
"product_id":"505-regular-fit-mens-jeans",
"title":"The 505 Regular Fit Men's Jeans",
"url":"https://levi.com/jeans/505-regular-fit-mens-jeans/",
"size":"29",
"material":"Cotton",
"color":"Rinse - Dark Wash",
"_search_score": 78.12,
"_personalization_score": 0.98
}
],
"spellcheck":{
"spelling_errors":false
}
}
}
product_id of the Product is
returned. You can ask Miso to return additional fields by using the fl parameter (see Request Body Schema below)According to a Microsoft Research study, roughly 10-15% of the queries sent to search engines contain errors. A misspelled search keyword often results in poor search quality, and users have been accustomed to Google’s automatic spelling correction functionality and expect the same on your site.
However, correcting spelling and typos at scale is a non-trivial machine learning problem. Miso’s spellcheck is based on a sequence-to-sequence deep learning model, trained and updated regularly on a corpus of billion tokens. It detects hard-to-spot errors, auto-correct keywords according to its context, and recognize terms that are newer or lesser known.
Spellcheck is always on for every search request so you don’t need to turn it on. What you need to decide is whether to turn on auto spelling correction. For example, the following search request turns on the auto-spelling-correction, and Miso will automatically replace any misspelled queries with their correct spelling:
POST /v1/search/search
{
"q":"whte denem jeans",
"user_id":"user-123",
"spellcheck":{
"enable_auto_spelling_correction":true
}
}
The API will respond:
{
"message":"success",
"data":{
"took":50,
"total":30,
"start":0,
"miso_id":"f34b90de-086b-11eb-b498-1ee8abb1818b",
"spellcheck":{
"spelling_errors":true,
"auto_spelling_correction":true,
"original_query":"whte denem jeans",
"original_query_with_markups":"<mark>whte</mark> <mark>denem</mark> jeans",
"corrected_query":"white denim jeans",
"corrected_query_with_markups":"<mark>white</mark> <mark>denim</mark> jeans"
},
"products":[
......
]
}
}
The spellcheck object contains the following fields:
<mark> html tags<mark> html tagsYou can opt-out the auto-spelling-correction by setting enable_auto_spelling_correction=false. For example:
POST /v1/search/search
{
"q":"whte denem jeans",
"user_id":"user-123",
"spellcheck":{
"enable_auto_spelling_correction":false
}
}
In this case, Miso will still run spellcheck against the query. However, users’ queries will be used as it is, and auto_spelling_correction field will be false.
While Miso’s personalized search can drive conversion by showing search results that are tailored to users’ interests, ultimately, it is important to make sure that the search results meet your business goals. To that end, Miso provides a great set of tools that enable you to fine-tune the search ranking and make it aligned with your goals.
One great example is boosting. Boosting allows you to define a query that can be used to boost a subset of products to the top of the ranking, or to specific boost positions. You can use boosting to run different kinds of promotion campaigns, or to promote certain set of products for individual users that you know they will be interested in.
For example, consider a scenario where you need to promote the sales of Nike’s products. Then, you might want to
use the query below, that will promote the sneakers whose brand are Nike to the top of the search result:
POST /v1/search/search
{
"q":"sneaker",
"user_id":"user-123",
"boost_fq": "brand:\"Nike\""
}
For a slightly more complex example, the query below will promote the Nike products which have also been tagged
as ON SALE:
POST /v1/search/search
{
"q":"sneaker",
"user_id":"user-123",
"boost_fq": "brand:\"Nike\" AND tags:\"ON SALE\""
}
You can have as complex boosting logic as you want in the boosting query, but it is worth mentioning that Miso will only boost products that are relevant and have high likelihood to convert. In other words, Miso will not boost low performance products even if they match the boosting query.
Depending on your boosting rules, in certain cases, you would like to prevent search results from becoming too “plain” due to boosting. For example, you don’t want the first page of the search result to contain only Nike products.
With Miso, you have two tools to avoid so. First, you can specify boost_positions to place boosted products at
specific positions in the ranking. For example, the query below will place boosted products only at the first,
fourth, seventh places in the ranking (positions are 0-based), and place the remaining products in their original
ranking, skipping these three positions.
POST /v1/search/search
{
"q":"sneaker",
"user_id":"user-123",
"boost_fq": "brand:\"Nike\" AND tags:\"ON SALE\"",
"boost_positions": [0, 3, 6]
}
The second tool is diversification. Miso’s diversification algorithm will maintain a desired minimum distance
between any two products that have the same attributes. For example, the
following query will make sure products made by the same brand are at least two slots apart from each
other in the search results.
POST /v1/search/search
{
"q":"sneaker",
"user_id":"user-123",
"boost_fq": "brand:\"Nike\" AND tags:\"ON SALE\"",
"diversification": {
"brand": {"minimum_distance": 2}
}
}
It is also very often to use both “boost_positions” and “diversification” at the same time to make sure that (1) the search results are not overwhelmed by the boosted products, and (2) there is a good mix of products from different brands showing side-by-side to increase product discovery rate.
You can override Miso’s default ranking order by specifing a list of fields for Miso to rank the search results. These fields can be any numeric or boolean fields in your Product catalog, or one of the following special fields:
geo must be specified when sorting with this field.For example, the following query returns all the Products (because q=*), ranked by the _personalization_score
first, and then by the values in the custom_attributes.promote_score field in the Product catalog, then the
distance between the product and New York city.
{
"q": "*",
"order_by": [
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.05"
},
"order": "desc"
},
{
"field": "custom_attributes.promote_score",
"order": "desc"
},
{
"field": "_geo_distance",
"geo": {
"lat": 40.711967,
"lon": -74.006076,
}
"order": "asc"
}
]
}
Miso supports mathematical functions that transform and combine different sorting criteria into one.
For example, a powerful strategy to improve gross merchandise volume (GMV), but maintain user
experience is
to sort the products based on the multiplication of personalization scores and product prices. You can achieve this with
the following order_by query:
{
"q": "*",
"order_by": [
{
"field": "_personalization_score * pow(sale_price, 0.5)",
"order": "desc"
}
]
}
Function pow(sale_price, 0.5) takes the square root of the sale price and avoids very expensive products from
overwhelming the ranking.
Miso supports all the common mathematical operators including +, -, *, /, %, ^, **, and more
advanced functions including:
pow(X, y), sqrt(X)exp(X), log(X), log2(X), log10(X)maximum(X, y), minimum(X, y)abs(X)round(X), floor(X), ceil(X)sin(X), cos(X), tan(X), asin(X), acos(X), atan(X)For scores that have granular resolutions, for example _personalization_score,_search_scores, or
Products’ sale_price, we usually don’t want to rank Products by their raw values. After all,
a 0.001 difference in _personalization_score or $0.01 difference in sale price typically will not make a
difference in users’ preferences. In such cases, soft tie-breakers should be used to smooth out these minor
differences in scores.
For example, in the query above, we apply a soft tie-breaker to _personalization_score based on score values’
relative difference. Specifically, we first sort the score’s raw values in the descending order, then
for two consecutive values, if their relative difference is no more than a pre-defined threshold
(in this case 0.05 or 5%), they are considered as a tie, and the next field
(i.e. custom_attributes.promote_score)
will be used to determine their ranking.
It is also common to utilize tie-breakers to combine the effect of two types of scores. For example, in the
following query, we set threshold=0.2 or 20% for _personalization_score, then only the
Products that users are 20% more likely to interact with will be ranked higher, the remaining Products will be
ranked by their sale prices. In this way, we combine the effect of personalization score and sale prices, where
the Products are roughly ranked by personalization, but favor the pricier products when they have comparable
personalization scores.
{
"q": "*",
"order_by": [
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.20"
},
"order": "desc"
},
{
"field": "sale_price",
"order": "desc"
}
]
}
Also note that, when search keywords are present, it is recommended to always include _search_score
as the first field (plus a tie-breaker) to maintain the relevance of the search results. A tie-breaker is usually
required as well to let the subsequent score have effect to the ranking.
{
"q": "toy story",
"order_by": [
{
"field": "_search_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.20"
},
"order": "desc"
},
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.20"
},
"order": "desc"
},
{
"field": "sale_price",
"order": "desc"
}
]
}
Your secret API key is used to access every Miso API endpoint. You should secure this key and only use it on a backend server. Never leave this key in your client-side JavaScript code. If the private key is compromised, you can revoke it in Dojo and get a new one.
Specify your secret key in the api_key query parameter. For example:
POST /v1/users?api_key=039c501ac8dfcac91c6f05601cee876e1cc07e17The engine you want to get results from. When you have more than one engine, you can use this parameter to specify the specific engine you want to get results from. If not specified, the default engine will be used.
The user who made the query and for whom Miso will personalize the results. For an anonymous visitor, use anonymous_id instead.
The anonymous visitor who made the query and for whom Miso will personalize the results. Either
user_id or anonymous_id needs to be specified for personalization to work.
The hash of user_id (or anonymous_id) encrypted by your Secret API Key.
user_hash is required to prevent unauthorized API access if you are
making API calls with a Publishable API Key.
You should generate the user_hash via HMAC scheme: you encrypt the desired user_id (or anonymous_id) with your Secret API Key on your backend server, and then let the front-end code send the generated user_hash to Miso APIs to verify the identity of the API caller.
As long as the Secret API Key is kept secret, the user_hash prevents a malicious attacker from making unauthorized API calls or impersonating any of your users.
Miso APIs accept the case-incentive "hex digest" of user hash, a sample Python 3 code to generate it on your backend server is as follow:
import hashlib
import hmac
YOUR_MISO_SECRET_API_KEY = "039c501ac8dfcac91"
key_bytes = YOUR_MISO_SECRET_API_KEY.encode()
user_id = "USER_123" # or anonymous_id
user_id_bytes = user_id.encode()
user_hash = hmac.new(
key_bytes,
user_id_bytes,
hashlib.sha256).hexdigest()
# user_hash is "7eb04da5e..."You can find more examples for other languages in this Github Gist
The user cohort you want to cold-start the recommendation with. For example, the following query will make
recommendations based on the preferences of the users whose country="United States", and gender="Female"
in the User Profile dataset.
{
"user_cohort": {
"country": "United States",
"gender": "Female"
}
}Number of search results to return.
The type of products to return. Use this parameter to make the API return only a certain type of products (see Product APIs).
This is particularly useful for sites that have multiple types of products: For example, on a marketplace site, YOu may model merchandise and store as two types of products. You can then use type parameter to limit the recommendation or search results to return only one kind of them.
For instance, the following query will return only store products:
{"type": "store"}For another example, on a travel website, you might have: hotel, thing to do, and restaurant,
three kinds
of products. You can use type parameter to limit results to one kind of them. For instance, the following
query will limit the results to only hotels product:
{"type": "hotel"}Whether to dedupe product based on product_group_id. If dedupe_product_group_id=true,
Miso will prevent products with the same product_group_id from showing multiple
times in the search or recommendation results.
This is particular useful when one product has multiple variants (for example, different sizes, colors, or materials), and you only want to show this product only once in the search or recommendation results. Miso will then return the variant that is most likely to be of the user's interest.
A list of additional interaction records. You can use this fields to simulate user interactions without actually writing them to the interaction dataset.
List of fields to retrieve. For example, the following request retrieves only the title field of each product along
with the product_id, which is always returned.
{"fl": ["title"]}You can also match field names by using * as a wildcard. For example, the query below retrieves the title
and any custom attributes under the attributes dictionary.
{"fl": ["title", "attributes.*"]}The following retrieves all the available fields:
{"fl": ["*"]}For the lowest latency, use an empty array to retrieve just the product_id field (which is the default).
{"fl": []}An array of product_ids of products you want to exclude from search results.
Dictionary of custom context variables for the current browsing session. You can specify context variables
specific to your websites or apps in a {"KEY":VALUE} format, where KEY must be a string, and VALUE can be:
boolstring or an array of stringnumber or an array of numbersarray of objectsnullIn certain cases, Miso will take these variables into account when generating results.
{
"session_variable_1": ["value_1", "value_2"]
}The search query the user has entered. Miso will perform full-text search and find any Products
that contain every word in this query. You can also set q="*" to match all Products, which is commonly used along
with Product filtering query fq to implement Category Pages.
(to make a search request, You need to specify either q or advanced_q)
1Like Google's Advanced Search, the advanced_q parameter let you define query beyond simple full-text
search. For one, you can use double-quotes to indicate a phrase search.
For example, the following query will only match Products that contain the phrase "Toy Story 4", and will not match Products like "4 Toy Story" (because the word order is not the same as the given query).
{"advanced_q": "full_text:\"Toy Story 4\""}If you don't want phrase search, you can enclose the search terms with parenthesis to indicate regular full-text query. For example:
{"advanced_q": "full_text:(Toy Story 4)"}You can also use AND/OR boolean operators to combine multiple full-text queries. For example, the following query will match Products with phrases "Toy Story 4" and Products with phrases "Toy Story 3", and will not match "Toy Story 2" or "Toy Story 1":
{"advanced_q":
"full_text:\"Toy Story 4\" OR full_text:\"Toy Story 3\""}Finally, you can use AND/OR boolean operators to combine full-text search with metadata filtering. For example, the following example will find Products with phrase "Toy Story" OR Products which have Tom Hanks as an actor.
{"advanced_q":
"full_text:\"Toy Story\" OR
custom_attributes.actors:\"Tom Hanks\""}(to make a search request, You need to specify either q or advanced_q)
1When boosting_tags is given, and there are pre-defined boost rules have the same tag(s),
those boost rules will be matched, regardless if the criteria is met or not.
Useful when want to force trigger specific boost campaign.
["tag-1", "quetag-2"]When set to true, enable user defined boosting campaigns.
By default boosting campaigns are enabled. But you can explicitly set this to false to disable boosting campaigns.
An array of product ids you want to include into search results, regardless if main query matches.
Two-letter (639-1) language code of the search query. This parameter is useful when you have a multilingual product catalog that contains product metadata in different languages. If given, the search results will prioritize the products that have that specific language and match the search query. Example query:
{"language": "fr"}If not given, Miso will search against all the languages in the catalog.
The text snippet that we want to find products that are similar to it
category parameter limits the search results to a particular category or sub-category.
This is particularly suitable for implementing Category Pages where
you want to show personalized ranking of Products under a specific category. Other filters, such as q,
fq, boost_fq will be applied on top of the category filter.
A category is represented by a list of strings that correspond to its category hierarchy.
For example, the following query returns Products under Snacks category:
{
"q": "*",
"category": ["Snacks"]
}And the following request returns Products under Snacks -> Chips subcategory:
{
"q": "*",
"category": ["Snacks", "Chips"]
}Spellcheck configuration
Specifies an offset from which Miso will begin returning results.
The default value is 0. Setting the start parameter to some other number, such as 3, causes Miso to skip over the
preceding products and start from the product identified by the offset.
A list of fields that Miso should use to sort the result, instead of Miso's default ranking order.
For example, the following query returns all the Products (because q=*), ranked by the _personalization_score
first, and then by the values in the custom_attributes.promote_score field in the Product catalog, then the
distance between the product and New York city.
{
"q": "*",
"order_by": [
{
"field": "_personalization_score",
"tie_breaker": {
"type": "relative_difference",
"threshold": "0.05"
},
"order": "desc"
},
{
"field": "custom_attributes.promote_score",
"order": "desc"
},
{
"field": "_geo_distance",
"geo": {
"lat": 40.711967,
"lon": -74.006076,
}
"order": "asc"
}
]
}Specifies a list of fields to create facet search against. You can specify facets in a string array.
For example, the following query return the facet counts for categories, tags, and custom_attributes.director:
{
"facets": [
"categories",
"tags",
"custom_attributes.director"
]
}The response will be like:
{
"facet_counts": {
"facet_fields": {
"categories": [
[
"Drama", 20
],
[
"Action", 10
], ...
],
"tags": [
[
"based on novel or book", 5
],
[
"android", 4
], ...
],
"custom_attributes.director": [
[
"Ridley Scott", 26
],
[
"Andrew Abbott", 1
], ...
}
}You can also specify facets with an object array to configure each facet individually.
For example, the following query will return 20 most common facet values for tags
and custom_attributes.director fields,
and only the directors whose names start with Ridley will be included in the director facet results.
{
"facets": [
{
"field": "tags",
"size": 20
},
{
"field": "custom_attributes.director",
"size": 20,
"include": "Ridley.*"
}
]
}Specifies filters to the search results based on users' selections in a faceted search UI.
For example, assume you have two facets in your faceted search UI: genres and custom_attributes.director.
When the user selects two options in the custom_attributes.director facet, you should send the following query to
filter the search results for those two options (i.e. Ridley Scott or Denis Villeneuve).
{
"facets": [
{
"field": "genres",
"size": 5
},
{
"field": "custom_attributes.director",
"size": 20
}
],
"facet_filters": {
"custom_attributes.director": {
"terms": [
"Ridley Scott",
"Denis Villeneuve"
]
}
},
}While you can use fq parameter to achieve the same filtering capability,
you should use facet_filters to get the correct facet counts.
In a typical faceted search UI, the facet counts reflect the search result after applying
filters from all but the current facets. For example, in the query below,
the directors facet counts
should reflect the search result after applying the filter from the genres facet, i.e. genres:Sci-Fi.
Similarly, genres facet counts should reflect the search result after applying the filter from the directors facet.
facet_filters will make the resulting facet_counts follow this all but except itself convention, which is rather
tricky to implement with fq.
"facets": [
{
"field": "genres",
"size": 5
},
{
"field": "custom_attributes.director",
"size": 20
}
],
"facet_filters": {
"custom_attributes.director": {
"terms": [
"Ridley Scott",
"Denis Villeneuve"
]
}
},
}Promote a product to a position relative to the highest-ranked anchor product.
A common use-case is promoting a private-label good by anchoring it to a name-brand counterpart. When the name-brand good (the anchor) appears in a search result, the private-label good also appears in the result (at a specified distance from the anchor product).
The anchoring_settings object has the following fields:
product_id of the product you want to promote.product_ids that act as the anchors.1 will place the promoted product directly after the anchor product. The default value is -1, which will place the promoted product directly before the anchor product.2022-01-29T00:00:00Z2022-05-31T23:59:59ZFor example, if a user searches for "cookies", the API request might look like this:
POST v1/search/search
{
"q":"cookies",
"anchoring_settings": [
{
"product_id": "private_label_cookies",
"anchor_ids": [
"name_brand_cookies_1",
"name_brand_cookies_2"
],
"relative_position": -1,
"start_time": "2022-01-01T00:00:00Z",
"end_time": "2022-12-31T23:59:59Z"
}
}
]
}A list of fields you want to exclude from matching the search keywords. If not specified, all fields will be considered. Curently, only certain fields are supported for exclusion.
For example, you might exclude the description field to improve search precision if the descriptions often contain misleading information.
{
exclude_fields_from_search: ["description"]
}In this example, the search will match the query against all fields except description.
title, subtitle, description, short_description, paragraphs, headers, anchors Enable partial match to return products that match only some of the keywords in a user's search query. By default, Miso's Search API only returns products that contain all the keywords in the search query (i.e. an AND operator over keywords). This strategy usually leads to highly relevant results. However, when we don't have enough search results to return to the users, enabling partial match allows the Search API to relax the criteria and return products that match only some of the keywords.
This strategy is particularly useful to prevent users from seeing an empty search result page and abandoning their search.
For example, let's consider the query request below:
{
"query": "Toy story 5",
"enable_partial_match": true
}Since there is no movie called "Toy story 5", we have zero products to return by default. However, because we set enable_partial_match to true, we will return other products that partially match the query:
{
"data": {
"products": [
{
"title": "Toy Story",
"_missing_keywords": ["5"]
},
{
"title": "Toy story 2",
"_missing_keywords": ["5"]
},
...
],
"total": 4
}
}As you can see from the result above, when we don't have the exact product that the user is looking for, enabling partial match is a helpful strategy to let users know what alternatives are available, and prevent them from seeing an empty search result page.
Determine which partial match mode to enable:
partial_match_mode is blended, keyword-matched items and semantically-matched items will
be returned in the same, rank-sorted array.partial_match_mode is separated, keyword-matched items will be returned in the products array
and partially-matched or semantically-matched items will be returned in the partially_matched_products array.blended, separated If partial_match_mode=separated, you need to provide a value for enable_partial_match_threshold.
This parameter, which accepts an integer (n), creates a condition for Miso’s Search Engine to only provide partially
matched results if there are n or fewer exact keyword matches. For example, if we set enable_partial_match_threshold=3,
partially matched results will only be returned when there are three or fewer exact keyword matches.
Enable semantic search to return products that are semantically relevant to the search query. Semantic search is a powerful tool that further improves the partial match results. It finds products that might not contain any of the search keywords, but are highly relevant to users' search intent.
For example, consider the query: rubbing alcohol, which is a household cleaning product. When enable_semantic_search=true,
even if we do not have any products that match rubbing alcohol, Miso is still able to return results like the
following:
{
"data": {
"products": [],
"total": 0,
"partially_matched_products": [
{
"title": "Clorox Disinfecting Wipes Multi-Surface Cleaning",
"_missing_keywords": ["rubbing", "alcohol"]
},
{
"title": "Purell Advanced Hand Sanitizer Refreshing Gel",
"_missing_keywords": ["rubbing", "alcohol"]
},
...
]
}
}Note that, these two products from Clorox or Purell do not contain any of the search keywords,
Miso's semantic search functionality, however, is still able to identify them as good matches based on their semantic
relevancy to the query rubbing alcohol.
Similarly, consider a single word search query: aspirin. Normally, a single-word query will lead to an empty search
page if we don't have products containing that word. However, when enable_semantic_search=true,
even if we do not directly have aspirin in the product catalog, Miso is still able to return results that are highly
relevant to users' search intent, such as:
{
"data": {
"products": [],
"total": 0,
"partially_matched_products": [
{
"title": "Advil Pain Reliever and Fever Reducer",
"_missing_keywords": ["aspirin"]
},
{
"title": "Tylenol Extra Strength Caplets",
"_missing_keywords": ["aspirin"]
},
...
]
}
}Determine the threshold for semantic search. Only the products with a semantic similarity score higher than the threshold will be returned. Setting this too low (e.g. < 0.3) will result in less relevant results being returned.
Determine whether to return _matched_fields in the search response (default: false).
If enable_matched_fields=true,
each returned product will have an _matched_fields array that shows which parts of the product catalog match
the search query.
For example, the following request will return _matched_fields:
{
"q": "toy story",
"enable_matched_fields": true
}The response will be like:
{
"data": {
"products": [
{
"title": "Toy Story",
"_matched_fields": ["title", "metadata"]
},
...
]
}
}Currently, _matched_fields only contain three kinds of fields:
titledescriptionmetadata, including all the fields beyond title or description in the product catalog.Additionally check if certain products will be in the search result at all (regardless of start and rows parameters)
Determines how much personalization will affect the search ranking.
0 <= x <= 5Defines a query in Solr syntax that can be used to restrict the superset of
products to return, without influencing the overall ranking. fq can enable users to drill down to products
with specific features based on different product attributes
For example, the query below limits the search results to only show products whose size is either M or S and
brand is Nike:
{"fq": "size:(\"M\" OR \"S\") AND brand:\"Nike\""}You can use fq to apply filters against your custom attributes as well. For example, the query below limits the
search results to only products whose designer attribute is Calvin Klein
{"fq": "attributes.designer:\"Calvin Klein\""}fq can also limit search results by numerical range. For example, the following query limits the results to
products that have rating >= 4.
{"fq": "rating:[4 TO *]"}Defines a query in Solr syntax that can be used to boost a subset of products to the top of the ranking, or to
specific boost positions (See boost_positions parameter below.)
For example, the query below will promote all the relevant products whose brand is Nike to the top of
recommendation list:
{
"boost_fq": "brand:\"Nike\""
}For a slightly more complex example, the query below will promote the Nike products which have also been tagged
as ON SALE to the top of the ranking:
{
"boost_fq": "brand:\"Nike\" AND tags:\"ON SALE\""
}It is worth mentioning that, Miso will only boost products that are relevant and have high likelihood to convert, and will not boost a low performance product only because it matches the boosting query.
Depending on your boosting rules, in certain cases, you would like to prevent recommendation results from being too monotone due to boosting. With Miso, you have two tools to do so.
First, you can specify boost_positions to place promoted products at specific positions in the ranking. For
example, the query below will place boosted products only at the first and fourth places in the ranking
(positions are 0-based), and place the remaining products in their original ranking, skipping these two positions.
{
"boost_fq": "brand:\"Nike\" AND tags:\"ON SALE\"",
"boost_positions": [0, 3]
}The second tool is diversification. diversification parameter, on a best-effort basis, will try to
maintain a minimum distance between products that have the same attributes. For example, the following query
will place products made by the same brand apart from each other.
{
"boost_fq": "brand:\"Nike\" AND tags:\"ON SALE\"",
"diversification": {
"brand": {"minimum_distance": 1}
}
}Defines a list of 0-based positions you want to place the boosted products at.
For example, the query below will promote products whose brand is Nike as the top and second recommendations:
{
"boost_fq": "brand:\"Nike\"",
"boost_positions": [0, 1]
}If boost_positions is not specified (which is the default behavior), all the boosted products will be ranked
higher than the rest of the products.
Name of the boosting rule. Use this to identify a boosting rule in _boosted_rules in the response
Define a list of boosting rules that will be applied to the search or recommendation results simultaneously. boost_rules
parameter is particularly useful when you want to boost more than one sets of products, and promote each of them to different
positions. For example, the query below will promote products whose brand is Nike to the top
and second results, and products whose brand is Adidas to the third and fourth results:
{
"boost_rules": [
{
"boost_fq": "brand:\"Nike\"",
"boost_positions": [0, 1]
},
{
"boost_fq": "brand:\"Adidas\"",
"boost_positions": [2, 3]
}
]
}When set, filter result to include only products within certain geographic range from given point will be returned, or to boost product within the same range.
Product should have a field that holds the location of the product, location is used by default,
but other field can also be used.
Distance can be in miles or kilometers. If distance_unit is not set, mile will be used.
For example, to limit results to products within 100 miles of New York city:
{
"geo": {
"filter": [{
"lat": 40.73061,
"lon": -73.93524,
"distance": 100
}]
}
}To boost products within 2 kilometers around Alcatraz Island according to loc field:
{
"geo": {
"boost": [{
"field": "loc",
"lat": 37.82667,
"lon": -122.42278,
"distance": 2,
"distance_unit": "km"
}]
}
}Defines diversification rules to prevent products with the same attributes (e.g. sneakers made by the same brand or books from the same authors) from showing up too close to each other in the results.
For instance, customers who have purchased many of sneakers from Nike may happen to have recommendations or search results where all top-5 entries are sneakers made by Nike. Purely considering accuracy, these recommendations appear excellent since the user clearly appreciates Nike sneakers. However, such results might be considered too "plain" by the user, owing to its lack of diversity.
diversification parameter allows you to avoid this problem by enforcing a desired minimum distance between
products. For example, consider a list of four products whose brand are Nike, Nike, Adidas, and PUMA
respectively. The query below will make sure there are at least one different product between two Nike
products, e.g. the diversified ranking may become Nike, Adidas, Nike, and PUMA :
{
"diversification": {"brand": {"minimum_distance": 1}}
}You can also increase the minimum_distance to place products further apart. For example, the following query will make sure, for the two Nike products, there are at least two other products between them. As a result, the diversified ranking may become Nike, Adidas, PUMA, and Nike.:
{
"diversification": {"brand": {"minimum_distance": 2}}
}The diversification algorithm reranks the products on a best-effort basis. For example, for the product list
described earlier, it is not possible to place two Nike product three places apart from each other. Therefore,
the diversified ranking will still remain Nike, Adidas, PUMA, and Nike* even if we set minimum_distance=3.