# Search API
# 1. Summary
The search endpoints retrieve documents from an index. Their returned documents are considered relevant based on the settings of the index and the provided search parameters.
# 2. Motivation
N/A
# 3. Functional Specification
Meilisearch exposes 2 routes to perform search requests:
GET
indexes/:index_uid/search
POST
indexes/:index_uid/search
π΄ Sending an invalid index uid format for the
:index_uid
path parameter returns an invalid_index_uid error.π΄ If the index does not exist, the API returns an index_not_found error.
If a master key is used to secure a Meilisearch instance, the auth layer returns the following errors:
- π΄ Accessing these routes without the
Authorization
header returns a missing_authorization_header error. - π΄ Accessing these routes with a key that does not have permissions (i.e. other than the master key) returns an invalid_api_key error.
POST
HTTP verb errors:
- π΄ Omitting the Content-Type header returns a missing_content_type error.
- π΄ Sending an empty Content-Type returns an invalid_content_type error.
- π΄ Sending a different Content-Type than
application/json
returns an invalid_content_type error. - π΄ Sending an empty payload returns a missing_payload error.
- π΄ Sending an invalid JSON payload returns a malformed_payload error.
# 3.1. Search Payload Parameters
Field | Type | Required |
---|---|---|
q | String | False |
filter | Array of String - String | False |
sort | Array of String - String | False |
facets | Array of String - String | False |
limit | Integer | False |
offset | Integer | False |
page | Integer | False |
hitsPerPage | Integer | False |
attributesToRetrieve | Array of String - String | False |
attributesToHighlight | Array of String - String | False |
highlightPreTag | String | False |
highlightPostTag | String | False |
attributesToCrop | Array of String - String | False |
cropLength | Integer | False |
cropMarker | String | False |
showMatchesPosition | Boolean | False |
showRankingScore | Boolean | False |
showRankingScoreDetails | Boolean | False |
matchingStrategy | String | False |
attributesToSearchOn | Array of String - String | False |
vector EXPERIMENTAL | Array of Float | False |
# 3.1.1. q
- Type: String
- Required: False
- Default:
null
q
contains the terms to search within the index documents.
When q isn't specified, Meilisearch performs a placeholder search. A placeholder search returns all searchable documents in an index, modified by any search parameters used and sorted by that index's custom ranking rules. If the index has no sort search parameter or custom ranking rules, the results are returned in the order of their internal database position.
Meilisearch only considers the first ten words of any given search query to deliver a fast search-as-you-type experience.
q
supports the Phrase Query expression.
- π΄ Sending a value with a different type than
String
ornull
forq
returns an invalid_search_q error.
# 3.1.2. filter
- Type: String (POST/GET) | Array of (String, Array of String) (POST)
- Required: False
- Default:
[]|null
filter
contains a filter expression written as a string or an array of (strings and array of strings). Its purpose is to refine search results by selecting documents that match the given filter and running the search query only on those documents.
Attributes used as filter criteria must be added to the filterableAttributes
list of an index settings. See Filterable Attributes Setting API.
- π΄ Sending a value with a different type than
String
(GET/POST),Array of (Array of String, String) (POST)
, ornull
forfilter
returns an invalid_search_filter error. - π΄ Sending an invalid syntax for
filter
returns an invalid_search_filter error. - π΄ Sending a field not defined as a
filterableAttributes
forfilter
returns an invalid_search_filter error.
# 3.1.2.1. String Syntax
# 3.1.2.1.1 Grammar
The grammar of the filter syntax is given below in pseudo-BNF form:
filter = expression EOF
expression = or
or = and ("OR" WS+ and)*
and = not ("AND" WS+ not)*
not = ("NOT" WS+ not) | primary
primary = "(" WS* expression WS* ")" | geoRadius | geoBoundingBox | in | condition | exists | not_exists | to
in = attribute "IN" WS* "[" value_list "]"
condition = attribute ("=" | "!=" | ">" | ">=" | "<" | "<=") value
exists = attribute "EXISTS"
not_exists = attribute "NOT" WS+ "EXISTS"
to = attribute value "TO" WS+ value
value = WS* ( word | singleQuoted | doubleQuoted) WS+
attribute = value
value_list = (value ("," value)* ","?)?
singleQuoted = "'" single_quoted_string "'"
doubleQuoted = "\"" double_quoted_string "\""
word = ([a-zA-Z0-9] | "_" | "-" | ".")+
geoRadius = "_geoRadius(" WS* float WS* "," WS* float WS* "," float WS* ")"
float = [+-]?[0-9]*("."[0-9]+)?(("E"|"e") [+-]?[0-9]+)?
WS = ' ' | '\t' | '\r' | '\n'
where single_quoted_string
and double_quoted_string
can contain anything except unescaped single quotes '
and unescaped double quotes "
, respectively. Quotes are escaped by a preceding backslash. For example: "escaped \" double quote" "
and escaped \' single quote
. If a backslash is not followed by the correct quote, it is kept in the string.
# 3.1.2.1.2 Naming a filterable attribute
A filterable attribute can appear in a filter by its unquoted name if it only contains ascii alphanumeric characters, dots, hyphens, and underscores.
For example, each filter below selects the documents where the given filterable attribute (on the left side of the equal) is equal to a specific value (on the right side):
genres = "film"
genre.subgenre = "adventure"
_geo.lat = 1.23
101 = "abc"
If the filterable attribute is composed of multiple words or contains other characters, it must be quoted, either using single quotes or double quotes:
"place of birth" = Berlin
"β" = 2.1
"Friend's name" = Albus
'opinion on "the best search engine"' = "meilisearch"
If the filterable attribute contains the same quote character that surrounds the attribute, then this quote character must be escaped by a preceding backslash:
'Friend\'s name' = Albus
# 3.1.2.1.3 Naming the value of a filterable attribute
The grammar for the value of a filterable attribute is the same as the grammar for filterable attributes themselves.
# 3.1.2.1.4 List of supported operators
- Equality:
attribute = value
- Inequality:
attribute != value
- Comparison:
attribute < value
attribute <= value
attribute > value
attribute >= value
attribute value TO value
- Exists:
attribute EXISTS
attribute NOT EXISTS
- IN:
attribute IN[value, value, etc.]
attribute NOT IN[value, value, etc.]
- IS EMPTY:
attribute IS EMPTY
attribute IS NOT EMPTY
- IS NULL:
attribute IS NULL
attribute IS NOT NULL
- AND:
filter AND filter
- OR:
filter OR filter
- NOT:
NOT filter
- GeoSearch:
_geoRadius(lat, lng, distance)
- GeoSearch:
_geoBoundingBox([lat, lng], [lat, lng])
# 3.1.2.1.5 Equality
The equality operator, =
, selects the documents for which:
- the given filterable attribute exists; and
- the attribute contains a value that is equal to a specific value
It is an infix operator that takes an attribute name on the left hand side and a value on the right hand side.
For example, given the documents:
[{
"id": 0,
"size": 1
},
{
"id": 1,
"size": ["1", "L"]
},
{
"id": 2,
}
{
"id": 3,
"size": "small"
"shop_distance": 1.2e+5
}]
then the filter:
size = 1
will select the documents with ids 0
and 1
.
Note that there is no way to specify whether the value on the right hand side of the equality should be interpreted as a string or as a number. Meilisearch will always try to match both. And since unquoted values cannot contain the +
character, it is in fact necessary to quote floating point numbers that have positive exponents:
shop_distance = "1.2e+5"
will select the document with id 3
.
Furthermore, there is no way to check whether an attribute has a value that is null
or an array. An attribute whose value is null
or an empty array is considered not to have any value and will therefore never be matched by an equality operator.
# 3.1.2.1.6 Inequality
The inequality operator selects all documents that are not selected by the equality operator. With the same documents given as examples to the equality operator, the following filter:
size != 1
will select the documents with ids 2
and 3
.
Note that attribute != value
is equivalent to NOT attribute = value
.
Furthermore, there is no way to write a filter to select documents which contain a value that is different than a given string or number. In the example above, size != 1
did not select the document with id 1
, even though its size
attribute contains the value "L"
, which is different than 1
.
# 3.1.2.1.7 Comparison
The comparison operators select the documents for which:
- the filterable attribute exists; and
- the attribute contains a number that satisfies the comparison
Note that the right hand side of the comparison must be a valid floating point number.
For example, with the documents:
[{
"id": 0,
"size": [0, "small"]
"colour": "blue"
},
{
"id": 1,
"size": 1
},
{
"id": 2,
"size": [2, 20]
}]
Then the following filters will select these documents:
size > 1 -> selects [1]
size >= 1 -> selects [1,2]
size < 2 -> selects [0,1]
size <= 2 -> selects [0,1,2]
size -1 TO 2 -> equivalent to size >= -1 AND size <= 2 -> selects [0,1,2]
And the following filters are invalid:
size > "small"
size "larga" TO "largz"
# 3.1.2.1.8 Combining filter conditions
Multiple filters can be combined together using the operators AND
and OR
. These infix operators take two sub-filters as arguments.
The AND
operator selects the documents that are selected by both subfilters at the same time. In other words, it is an intersection of the two sets of documents selected by the sub-filters.
The OR
operator selects the documents that are selected by either operator. In other words, it is a union of the two sets of documents selected by the sub-filters.
Note that AND
has a higher precedence than OR
. Therefore, the following filter:
x = 1 AND y = 2 OR z = 3
will be interepreted as:
(x = 1 AND y = 2) OR (z = 3)
With the same documents given as examples for the comparison operators, the following filters will select these documents:
size = 0 OR size = 1 -> selects [0,1]
size = 0 AND (size = 2 OR colour = "blue") -> selects []
size = 0 AND size = 2 OR colour = "blue" -> selects [0]
size > 5 AND size < 5 -> selects [2]
# 3.1.2.1.9 Negating a filter
The negation operator, NOT
, is used to select all documents that are not selected by a sub-filter. It is a prefix operator that takes one argument. Its precedence is higher than both AND
and OR
.
With the same documents given as examples for the comparison operators, the following filters will select these documents:
NOT size = 0 -> selects [1,2]
NOT (size = 0 OR size = 1) -> selects [2]
NOT size = 0 OR size = 1 -> selects [1,2]
NOT (size < 2 AND colour = "blue") -> selects [1,2]
NOT size < 2 AND colour = "blue" -> selects []
size = 0 OR NOT size = 2 -> selects [0,1]
NOT (NOT size = 0) -> selects [0]
# 3.1.2.1.10 EXISTS
The EXISTS
operator selects the documents for which the filterable attribute exists, even if its value is null
or an empty array. It is a postfix operator that takes an attribute name as argument.
The negated form of EXISTS
can be written in two ways:
attribute NOT EXISTS
NOT attribute EXISTS
Both forms are equivalent. They select the documents for which the attribute does not exist.
For example, with the documents:
[{
"id": 0,
"colour": []
},
{
"id": 1,
"colour": null
},
{
"id": 2
}]
Then the filter colour EXISTS
selects the document ids [0,1]
while the filter colour NOT EXISTS
or NOT colour EXISTS
selects the document ids [2]
.
# 3.1.2.1.11 IN
The IN[..]
operator is a more concise way to combine equality operators. It is a postfix operator that takes an attribute name on the left hand side and an array of values on the right hand side. An array of value is a comma-separated list of values delimited by square brackets.
The two filters below are equivalent:
attribute IN[value1, value2, value3,]
attribute = value1 OR attribute = value2 OR attribute = value3
In short, IN
selects the documents for which:
- the filterable attribute exists; and
- the attribute contains a value that is equal to any of the values in the array
The negated form of IN
can be written in two different ways:
attribute NOT IN [value1, value2, etc.]
NOT attribute IN [value1, value2, etc.]
and it is equivalent to:
attribute != value1 AND attribute != value2 AND ...
# 3.1.2.1.12 Geo Search
- The
_geoRadius
operator selects the documents whose geographical coordinates fall within a certain range of a given coordinate. See GeoSearch for more information. - The
_geoBoundingBox
operator selects the documents whose geographical coordinates fall within a square described by the given coordinates. See GeoSearch for more information.
# 3.1.2.1.12 IS EMPTY
The IS EMPTY
operator selects the documents for which the filterable attribute exists and is empty. If the attribute doesn't exists then it is not empty and the document will not be returned. It is a postfix operator that takes an attribute name as argument.
The negated form of IS EMPTY
can be written in two ways:
attribute IS NOT EMPTY
NOT attribute IS EMPTY
Both forms are equivalent. They select the documents for which the attribute is not empty.
Here is the list of JSON values that are considered empty:
""
[]
{}
For example, with the documents:
[{
"id": 0,
"colour": []
},
{
"id": 1,
"colour": null
},
{
"id": 2,
"colour": ""
},
{
"id": 3,
"colour": {}
},
{
"id": 4
}]
Then the filter colour IS EMPTY
selects the document ids [0,2,3]
while the filter colour IS NOT EMPTY
or NOT colour IS EMPTY
selects the document ids [1,4]
.
# 3.1.2.1.13 IS NULL
The IS NULL
operator selects the documents for which the filterable attribute exists and is null
. If the attribute doesn't exists then it is not null
and the document will not be returned. It is a postfix operator that takes an attribute name as argument.
The negated form of IS NULL
can be written in two ways:
attribute IS NOT NULL
NOT attribute IS NULL
Both forms are equivalent. They select the documents for which the attribute is not null
.
For example, with the documents:
[{
"id": 0,
"colour": []
},
{
"id": 1,
"colour": null
},
{
"id": 2,
"colour": ""
},
{
"id": 3,
"colour": {}
},
{
"id": 4
}]
Then the filter colour IS NULL
selects the document ids [1]
while the filter colour IS NOT NULL
or NOT colour IS NULL
selects the document ids [0,2,3,4]
.
# 3.1.2.2. Array Syntax
The array syntax is an alternative way to combine different filters with OR
and AND
operators.
- Elements in the outer array are connected by
AND
operators - Elements in the inner arrays are connected by
OR
operators
Example:
{
"filter": [["genres = Comedy", "genres = Romance"], "director = 'Mati Diop'"]
}
is equivalent to:
{
"filter": "(genres = Comedy OR genres = Romance) AND (director = 'Mati Diop')"
}
# 3.1.3. sort
- Type: Array of String (POST) | String (GET)
- Required: False
- Default:
[]|null
sort
contains a sort expression written as a string or an array of strings. It sorts the search results at query time according to the specified attributes and indicated order.
Attributes used as sort criteria must be added to the `sortableAttributes list of an index settings. See Sortable Attributes Setting API.
- π΄ Sending a value with a different type than
Array of String
(POST),String
(GET) ornull
forsort
returns an invalid_search_sort error. - π΄ Sending an invalid syntax for
sort
returns an invalid_search_sort error. - π΄ Sending a field not defined as a
sortableAttributes
forsort
returns an invalid_search_sort error.
See Sort
# 3.1.4. facets
- Type: Array of String (POST) | String (GET)
- Required: False
- Default:
[]|null
facets
permits to specify facets to be computed for the current search query.
It returns the number of documents matching the current search query for each specified facet.
This parameter can take two values:
- An array of attributes:
facets=["attributeA", "attributeB", β¦]
- A wildcard
"*"
β this returns a count for all facets present infilterableAttributes
Attributes used in facets
must be added to the filterableAttributes
list of an index settings. See Filterable Attributes Setting API.
- π΄ Sending a value with a different type than
Array of String
(POST),String
(GET) ornull
forfacets
returns an invalid_search_facets error. - π΄ Sending a field not defined as a
filterableAttributes
forfacets
returns an invalid_search_facets error.
The distribution of the different facets is returned in the facetDistribution
response parameter.
Statistics are computed and returned within the facetStats
object for distributed facets. See facetStats
section.
# 3.1.5. limit
- Type: Integer
- Required: False
- Default:
20
Sets the maximum number of documents to be returned for the search query.
If in addition to either page
and/or hitsPerPage
, limit
and/or offset
are provided as well, limit
and offset
are ignored. See explaination.
- π΄ Sending a value with a different type than
Integer
forlimit
returns an invalid_search_limit error.
# 3.1.6. offset
- Type: Integer
- Required: False
- Default:
0
Sets the starting point in the search results, effectively skipping over a given number of documents.
If in addition to either page
and/or hitsPerPage
, limit
and/or offset
are provided as well, limit
and offset
are ignored. See details.
- π΄ Sending a value with a different type than
Integer
foroffset
returns an invalid_search_offset error.
# 3.1.7. page
- Type: Integer
- Required: False
- Default:
null
Sets the specific results page to fetch.
By default, page is null
, or 1
if hitsPerPage
is provided.
The first page has a value of 1
, the second 2
, etc... When 0
is provided as a value, no hits are returned.
When providing page
or hitsPerPage
in the query parameters, the page selection
system is enabled, which makes it possible to navigate through the search results pages. See explanation on the page selection
.
If in addition to either page
and/or hitsPerPage
, limit
and/or offset
are provided as well, limit
and offset
are ignored. See explanation.
- π΄ Sending a value with a different type than
Integer
forpage
returns an invalid_search_page error.
# 3.1.8. hitsPerPage
- Type: Integer
- Required: False
- Default:
null
Sets the number of results returned for a query.
By default, hitsPerPage
is null
, or 20
if page
is provided. When 0
is provided as a value, no hits are returned.
When providing page
or hitsPerPage
in the query parameters, the page selection
system is enabled, which makes it possible to navigate through the search results pages. See explanation on the page selection
.
If in addition to either page
and/or hitsPerPage
, limit
and/or offset
are provided as well, limit
and offset
are ignored. See explaination.
- π΄ Sending a value with a different type than
Integer
forhitsPerPage
returns an invalid_search_hits_per_page error.
# 3.1.8.1. Navigating search results by page selection
By default, limit
and offset
are used to navigate search results. While being performant, it lacks exhaustiveness to create a seamless page selection navigation. Upon using limit
/offset
, estimatedTotalHits
is returned, which provides a rough estimation of how many hits may be candidates for a given request. See limit
/offset
usage for further explanation.
The page selection
system provides an alternative that tackles the above-mentioned issue when reliable information is needed to navigate results with a page selector. e.g. A page selector component << < 1, 2, 3, ...14 > >>
. Nonetheless, it's considered less performant on a larger number of results as the engine needs to compute the totalHits
exhaustively.
With this page selection system, it is possible to jump from one page to another using the page
parameter and decide how many results should be returned per page with the hitsPerPage
parameter. See page
/hitsPerPage
usage for further explanation.
# 3.1.8.1.1. Limit/offset usage
When either limit
or offset
is specified or when neither limit
, offset
, page
and hitsPerPage
are specified, the response object contains the related fields:
If in addition to limit
and/or offset
, either page
or hitsPerPage
is also provided, limit
and offset
parameters are ignored.
For example, given the following query parameters:
- limit: 10
- offset: 1
The response objects contain these specific fields:
{
"hits": [
/// ... 10 hits
],
/// ... other fields
"limit": 10,
"offset": 1,
"estimatedTotalHits": 1345
}
For example, on a query with no query parameters:
The response objects contain these specific fields:
{
"hits": [
/// ... 10 hits
],
/// ... other fields
"limit": 20,
"offset": 0,
"estimatedTotalHits": 1345
}
# 3.1.8.1.2 page/hitsPerPage usage
As soon as either page
or hitsPerPage
is used as a query parameter, in the response object, limit
, offset
, and estimatedTotalHits
are removed and page selection related fields are returned:
hitsPerPage
: number of results per page.page
: current search results page. The counting starts at1
.totalPages
: total number of results pages. Calculated usinghitsPerPage
value.totalHits
: total number of search results.
Both totalPages
and totalHits
are computed until they reach the pagination.maxTotalHits
number from the settings.
If in addition to either page
and/or hitsPerPage
, limit
and/or offset
are provided as well, limit
and offset
are ignored.
For example, given the following query parameters:
- page: 2
- hitsPerPage: 10
The response objects contain these specific fields:
{
"hits": [
/// ... 10 hits
],
/// ... other fields
"page": 2,
"hitsPerPage": 10,
"totalHits": 2100,
"totalPages": 210
}
For example, given the following query parameters:
- page: 2
- hitsPerPage: 10
- limit: 1
The response objects contain these specific fields:
{
"hits": [
/// ... 10 hits
],
/// ... other fields
"page": 2,
"hitsPerPage": 10,
"totalHits": 2100,
"totalPages": 210
}
For example, given the following query parameters:
- page: 0
- hitsPerPage: 10
The response objects contain these specific fields:
{
"hits": [],
/// ... other fields
"page": 0,
"hitsPerPage": 10,
"totalHits": 2100,
"totalPages": 210
}
# 3.1.9. attributesToRetrieve
- Type: Array of String (POST) | String (GET)
- Required: False
- Default:
["*"]
, meaning all the attributes
Configures which attributes will be retrieved in the returned documents.
If no value is specified, the default value of attributesToRetrieve
is used (["*"]
). This corresponds to the displayedAttributes
index setting, which by default contains all attributes found in the documents.
If an attribute is missing from
displayedAttributes
index setting,attributesToRetrieve
silently ignore it, and the field doesn't appear in the returned search results.
- π΄ Sending a value with a different type than
Array of String
(POST),String
(GET) ornull
forattributesToRetrieve
returns an invalid_search_attributes_to_retrieve error.
# 3.1.10. attributesToHighlight
- Type: Array of String (POST) | String(GET)
- Required: False
- Default:
[]|null
Configures which fields may have highlighted parts, given that they match the requested query terms (i.e. the terms in the q
search parameter). Pre/post highlighting tags are applied around each word corresponding to a query term.
If attributesToHighlight
is present in the search query, the search results will include a _formatted
object containing the attributes and their highlighted parts. For more detailed regarding the _formatted
behavior, see the 3.2.1.1.2. _formatted
section.
If "*"
is provided as a value (attributesToHighlight=["*"]
), all the attributes present in displayedAttributes
setting will be highlighted.
Highlighted parts are surrounded by the highlightPreTag
and highlightPostTag
parameters.
attributesToHighlight
only works on values of the following types: string
, number
, array
, object
. When highlighted, number attributes are transformed to string.
- π΄ Sending a value with a different type than
Array[String]
(POST),String
(GET) ornull
forattributesToHighlight
returns an invalid_search_attributes_to_highlight error.
# 3.1.10.1. searchableAttributes
Attributes not defined in the searchableAttributes
index setting are also highlighted if assigned to attributesToHighlight
.
# 3.1.10.2. stopWords
Attributes defined in the stopWords
index setting are also highlighted if matched.
# 3.1.10.3. Tokenizer Separators
Tokenizer separators are not highlighted.
# 3.1.10.4. synonyms
Synonyms are also highlighted.
# 3.1.11. highlightPreTag
- Type: String
- Required: False
- Default:
"<em>"
Specifies the string to put before every highlighted query terms.
This parameter is applied to the fields configured in attributesToHighlight
. If there are none, this parameter has no effect. See 3.1.10. attributesToHighlight
section.
- π΄ Sending a value with a different type than
String
forhighlightPreTag
returns an invalid_search_highlight_pre_tag error.
If attributesToHighlight
is omitted while highlightPreTag
is specified, there is no error.
# 3.1.12. highlightPostTag
- Type: String
- Required: False
- Default:
"</em>"
Specifies the string to put after the highlighted query terms.
This parameter is applied to the fields from attributesToHighlight
. If there are none, this parameter has no effect. See 3.1.10. attributesToHighlight
section.
- π΄ Sending a value with a different type than
String
forhighlightPostTag
returns an invalid_search_highlight_post_tag error.
If attributesToHighlight
is omitted while highlightPostTag
is specified, there is no error.
# 3.1.13. attributesToCrop
- Type: Array[String]|String
- Required: False
- Default:
[]|null
Defines document attributes to be cropped. Cropped attributes have their values shortened around query terms.
If attributesToCrop
is present in the search query, the search results will include a _formatted
object containing the attributes and their cropped parts. For more detailed regarding the _formatted
behavior, see the 3.2.1.1.2. _formatted
section.
If "*"
is provided as a value (attributesToCrop=["*"]
), all the attributes present in displayedAttributes
setting will be cropped.
The number of words contained in the cropped value is defined by the cropLength
parameter. See 3.1.1.14. cropLength
section.
The value of cropLength
can be customized per attribute. See 3.1.12.1. Custom cropLength
Defined Per Cropped Attribute section.
The engine adds a marker by default in front of and/or behind the part selected by the cropper. This marker is customizable. See 3.1.13. cropMarker
section.
- π΄ Sending a value with a different type than
Array[String]
(POST),String
(GET) ornull
forattributesToCrop
returns an invalid_search_attributes_to_crop error.
# 3.1.13.2. searchableAttributes
Attributes configured in attributesToCrop
are cropped even if not present in the searchableAttributes
index setting.
# 3.1.13.3. stopWords
Terms defined in the stopWords
index setting are counted as words regarding cropLength
.
# 3.1.13.3. Tokenizer Separators
Tokenizer separators aren't counted as words regarding cropLength
.
# 3.1.14. cropLength
- Type: Integer
- Required: False
- Default:
10
Sets the total number of words to keep for the cropped part of an attribute specified in the attributesToCrop
parameter. It means that if 10
is set for cropLength
, the cropped part returned in _formatted
will only be 10 words long.
This parameter is applied to the fields from attributesToCrop
. If there are none, this parameter has no effect. See 3.1.13. attributesToCrop
section.
Sending a 0
value deactivates the cropping unless a custom crop length is defined for an attribute inside attributesToCrop
.
- π΄ Sending a value with a different type than
Integer
forcropLength
returns an invalid_search_crop_length error.
# 3.1.14.1. Custom cropLength
Defined Per Attribute.
Optionally, indicating a custom crop length for any of the listed attributes is possible:
"attributesToCrop":["attributeNameA:15", "attributeNameB:30"]
A custom crop length set in this way has priority over the cropLength
parameter.
# 3.1.14.2 Examples
# 3.1.14.1.1. Extending around
Given an attribute defined in attributesToCrop
containing:
"In his ravenous hatred he found no peace, and with boiling blood he scoured the umbral plains, seeking vengence afgainst the dark lords who had robbed him."
With croplength
defined as 5
and q
defined as boiling blood
, the cropped value will be:
"β¦and with boiling blood heβ¦"
Cropped query terms are counted as a word regarding cropLength
.
Sending more query terms than the cropLength
value has no impact. The cropped part will contain the cropLength
number.
# 3.1.14.1.2. Keeping a phrase context
After Meilisearch has chosen the best possible match window (some number of words < cropLength
), it will add words from before or after the match window until the total number is equal to cropLength
. In doing so, it will attempt to add context to the match window by choosing words from the same sentence(s) where the match window occurs.
For instance, for the matching word Split
the text:
"Natalie risk her future. Split The World is a book written by Emily Henry. I never read it."
will be cropped like:
β¦Split The World is a book written by Emily Henryβ¦
and not like:
Natalie risk her future. Split The World is a bookβ¦
# 3.1.15. cropMarker
- Type: String
- Required: False
- Default:
"β¦"
(U+2026)
Sets which string to add before and/or after the cropped text. See 3.1.13. attributesToCrop
section.
The specified crop marker is applied by following rules outline in section 3.1.15.1. Applying cropMarker
.
Specifying cropMarker
to ""
or null
implies that no marker will be applied to the cropped part.
This parameter is applied to the fields configured in attributesToCrop
. If there are none, this parameter has no effect. See 3.1.13. attributesToCrop
section.
- π΄ Sending a value with a different type than
String
ornull
forcropMarker
returns an invalid_search_crop_marker error.
# 3.1.15.1. Applying cropMarker
# 3.1.15.1.1. Matched Part To Be Cropped
The cropping algorithm tries to match the window with the highest density of query terms within the cropLength
limit.
The cropping algorithm tries to find the crop window that contains the most relevant matches.
- That has the highest count of unique matches
For example, for the query terms split the world
, then the interval the split the split the
has 5
matches but only 2
unique matches (1
for split
and 1
for the
) where the interval split of the world
has 3
matches and 3
unique matches. So the interval split of the world
is considered better.
- That have the minimum distance between matches
For example, for the query terms split the world
, then the interval split of the world
has a distance of 3
(2
between split
and the
, and 1
between the
and world
) where the interval split the world
has a distance of 2
. So the interval split the world
is considered better.
- That have the highest count of ordered matches
For example, for the query terms split the world
, then the interval the world split
has 2
ordered words where the interval split the world
has 3
. So the interval split the world
is considered better.
Only one cropped part from an attribute is returned.
If no part is found when selecting a part to be cropped, the returned value in _formatted
will start at the beginning of the attribute and include a number of words equal to cropLength
.
# 3.1.15.1.2. Positioning Markers
If the cropped part has been matched against query terms and contains the beginning of the attribute to be cropped, the cropMarker
is not placed to the left of the cropped part.
If the cropped part has been matched against query terms and contains the end of the attribute to be cropped, the cropMarker
is not placed to the right of the cropped part.
# 3.1.16. showMatchesPosition
- Type: Boolean
- Required: False
- Default:
false
Adds a _matchesPosition
object to the search response that contains the location of each occurrence of queried terms across all fields. The given positions are in bytes.
It's useful when more control is needed than offered by the built-in highlighting/cropping features.
- π΄ Sending a value with a different type than
Boolean
ornull
forshowMatchesPosition
returns an invalid_search_show_matches_position error.
# 3.1.17. showRankingScore
- Type: Boolean
- Required: False
- Default:
false
Adds a _rankingScore
number to each document in the search response, representing the relevancy score of a document according to the applied ranking rules and relative to a search query. Higher is better.
1.0
indicates a perfect match, 0.0
no match at all (Meilisearch should not return documents that don't match the query).
- π΄ Sending a value with a different type than
Boolean
ornull
forshowRankingScore
returns an invalid_search_ranking_score error.
# 3.1.18. showRankingScoreDetails
- Type: Object
- Required: False
- Default:
false
Adds a _rankingScoreDetails
object to each document in the search response, containing information about the score of that document for each applied ranking rule.
- π΄ Sending a value with a different type than
Boolean
ornull
forshowRankingScoreDetails
returns an invalid_search_ranking_score_details error.
# 3.1.19. matchingStrategy
- Type: String
- Required: False
- Default:
last
Defines which strategy to use to match the query terms within the documents as search results.
Two different strategies are available, last
and all
. By default, the last
strategy is chosen.
- π΄ Sending a value with a different type than
String
and other thanlast
orall
as a value formatchingStrategy
returns an invalid_search_matching_strategy error.
# 3.1.19.1. last
strategy
The documents containing ALL the query words (i.e. in the q
parameter) are returned first by Meilisearch. If Meilisearch doesn't have enough documents to fit the requested limit
, it iteratively ignores the query words from the last typed word to the first typed word to match more documents.
# 3.1.19.2. all
strategy
Only the documents containing ALL the query words (i.e. in the q
parameter) are returned by Meilisearch. If Meilisearch doesn't have enough documents to fit the requested limit
, it returns the documents found without trying to match more documents.
# 3.1.20. attributesToSearchOn
- Type: Array of String (POST) | String (GET)
- Required: False
- Default:
["*"]
Defines which searchableAttributes
the query will search on.
- If
attributesToSearchOn
is not set, set to["*"]
or set tonull
, then the query will search on allsearchableAttributes
. - Sending the attributes in a different order than the order set in the settings
searchableAttributes
doesn't reorder the fields' rank for theAttributes
ranking rule - π΄ Sending a value with a different type than
Array of String
(POST),String
(GET) ornull
forattributesToSearchOn
returns an invalid_attributes_to_search_on error. - π΄ Sending an attribute that is not part of the settings
searchableAttributes
list returns an invalid_attributes_to_search_on error.
# 3.1.21. vector
EXPERIMENTAL
- Type: Array of Float
- Required: False
- Default: []
Request the nearest documents based on the query vector embedding given.
- π΄ Sending a value with a different type than
Array of Float
ornull
as a value forvector
returns an invalid_search_vector error. - π΄ Sending a value for
vector
whose length differs from the documents_vectors
length returns an invalid_search_vector error.
# 3.2. Search Response Properties
Field | Type | Required |
---|---|---|
hits | Array[Hit] | True |
limit | Integer | False |
offset | Integer | False |
estimatedTotalHits | Integer | False |
page | Integer | False |
hitsPerPage | Integer | False |
totalPages | Integer | False |
totalHits | Integer | False |
facetDistribution | Object | False |
facetStats | Object | False |
processingTimeMs | Integer | True |
query | String | True |
vector EXPERIMENTAL | Array of Float | False |
# 3.2.1. hits
- Type: Array[Hit]
- Required: True
Results of the search query as an array of documents.
Hit object represents a matched document as a search result.
The search parameters
attributesToRetrieve
influence the returned payload for a hit. See 3.1.7.attributesToRetrieve
section.
A search result can contain special properties. See 3.2.1.1. hit
Special Properties section.
# 3.2.1.1. hit
Special Properties
Field | Type | Required |
---|---|---|
_geoDistance | Integer | False |
_formatted | Object | False |
_matchesPosition | Object | False |
_rankingScore | Number | False |
_rankingScoreDetails | Object | False |
_semanticScore EXPERIMENTAL | Float | False |
# 3.2.1.1.1. _geoDistance
- Type: Integer
- Required: False
Search queries using _geoPoint
returns a _geoDistance
field containing the distance in meters between the document _geo
coordinates and the specified _geoPoint
.
See GeoSearch
# 3.2.1.1.2. _formatted
- Type: Object
- Required: False
_formatted
is an object returned in the search response, only if at least one of the following paramaters has been set in the search query:
attributesToHighlight
attributesToCrop
If attributesToHighlight
and attributesToCrop
are not set, _formatted
is not returned.
This _formatted
object will be present in each returned document in the hits
field.
Example:
{
"attributesToCrop": ["title"]
}
{
"hits": [
{
"id": 2,
"title": "Pride and Prejudice",
"_formatted": {
"id": "2",
"title": "Pride and Prejudice"
}
},
{
"id": 456,
"title": "Le Petit Prince",
"_formatted": {
"id": "456",
"title": "Le Petit Prince",
}
}
],
...
}
Which attributes are present in _formatted
?
Remember the main rule: _formatted
is only present if attributesToHighlight
or attributesToCrop
is set.
The _formatted
object contains attributes coming from the original document, depending on the parameters the users set during the search query. Indeed, _formatted
contains all the attributes present in attributesToRetrieve
, attributesToHighlight
, and attributesToCrop
combined.
Knowing the default value of attributesToRetrieve
is ["*"]
(so all the attributes present in displayedAttributes
), if no attributesToRetrieve
are set in the search query, _formatted
will return all the displayedAttributes
.
Returning attributes in the _formatted
object does not mean these attributes will be necessarily highlighted or cropped, see the next point.
Which attributes are highlighted or cropped in _formatted
?
No matter which attributes are retrieved in _formatted
(according to the previous section "Which attributes are present in _formatted
?"):
- Only the attributes present in
attributesToHighlight
are highlighted. - Only the attributes present in
attributesToCrop
are cropped. - Attributes present in both are cropped and highlighted at the same time.
Some edge cases:
- If cumulated fields in
attributesToHighlight
andattributesToCrop
resolve to only having non-existent fields,_formatted
is not returned.
Some examples:
The examples work the same with attributesToCrop
Example 1:
{
"q": "t",
"attributesToHighlight": ["title"]
}
{
"hits": [
{
"id": 1,
"title": "The Hobbit",
"author": "J. R. R. Tolkien",
"_formatted": {
"id": "1",
"title": "<em>T</em>he Hobbit",
"author": "J. R. R. Tolkien"
}
}
],
...
}
-> All the attributes (so id
, title
and author
) are returned in _formatted
because by default attributesToRetrieve
is set to ["*"]
.
-> Only title
is highlighted.
Example 2:
{
"q": "t",
"attributesToHighlight": ["*"]
}
{
"hits": [
{
"id": 1,
"title": "The Hobbit",
"author": "J. R. R. Tolkien",
"_formatted": {
"id": "1",
"title": "<em>T</em>he Hobbit",
"author": "J. R. R. <em>T</em>olkien"
}
}
],
...
}
-> id
, title
and author
are returned in _formatted
becauseattributesToHighlight
is set to ["*"]
(but also attributesToRetrieve
by default).
-> Both title
and author
are highlighted because attributesToHighlight
is set to ["*"]
.
Example 3:
{
"q": "t",
"attributesToRetrieve": ["author"],
"attributesToHighlight": ["title"]
}
{
"hits": [
{
"author": "J. R. R. Tolkien",
"_formatted": {
"title": "<em>T</em>he Hobbit",
"author": "J. R. R. Tolkien"
}
}
],
...
}
-> Only author
is returned at the root of the document because defined in the attributesToRetrieve
.
-> Only author
and title
are returned in _formatted
because the addition of attributesToRetrieve
and attributesToHighlight
.
-> Only title
is highlighted because the only one defined in attributesToHighlight
.
Example 4:
{
"q": "t",
"attributesToRetrieve": [],
"attributesToHighlight": ["*"]
}
{
"hits": [
{
"_formatted": {
"id": "1",
"title": "<em>T</em>he Hobbit",
"author": "J. R. R. <em>T</em>olkien"
}
}
],
...
}
-> No attributes are returned at the root of the document because attributesToRetrieve
is set to []
.
-> All the attributes are returned in _formatted
because attributesToHighlight
is set to ["*"]
.
-> All the attributes are highlighted because attributesToHighlight
is set to ["*"]
.
# 3.2.1.1.3. _matchesPosition
- Type: Object
- Required: False
Contains the location of each occurrence of queried terms across all fields. The _matchesPosition
object is added to a search result when the showMatchesPosition
search parameter is specified to true.
The beginning of a matching term within a field is indicated by start
, and its length
by length.
start
and length
are measured in bytes and not the number of characters. For example, ΓΌ
represents two bytes but one character.
See 3.1.14.
showMatchesPosition
section.
# 3.2.1.1.4. _rankingScore
- Type: Number
- Required: False
The relevancy score of a document relative to the search query. Higher is better.
1.0
indicates a perfect match, 0.0
no match at all (Meilisearch should not return documents that don't match the query).
See Ranking Score for details.
# 3.2.1.1.5. _rankingScoreDetails
- Type: Object
- Required: False
The ranking score of a document per each ranking rule and relative to the search query.
This object features one field for each applied ranking rule, whose values are an object with at least the field order
indicating in which order this ranking rule has been applied.
See Ranking Score details for details.
# 3.2.1.1.6. _semanticScore
EXPERIMENTAL
- Type: Float
- Required: False
Contains the semantic similarity score of the document for a vector search when vector
has been provided. The score is represented as a dot product.
See 3.1.18
vector
# 3.2.2. limit
- Type: Integer
- Required: False
Returns the limit
search parameter used for the query.
This field is returned only when:
limit
and/oroffset
are used as query parameters.- None of
limit
,offset
,page
,hitsPerPage
are used as a query parameter
See details on the different ways of navigating search results.
See 3.1.5.
limit
section.
# 3.2.3. offset
- Type: Integer
- Required: False
Returns the offset
search parameter used for the query.
This field is returned only when none of page
and hitsPerPage
are used as a query parameter.
See explanation on the different ways of navigating search results.
See 3.1.6.
offset
section section.
# 3.2.4. estimatedTotalHits
- Type: Integer
- Required: False
Returns the estimated number of candidates for the search query. This field is returned only when limit
or/and offset
are used as a query parameter.
This field is returned only when:
limit
and/oroffset
are used as query parameters.- None of
limit
,offset
,page
,hitsPerPage
are used as a query parameter
See details on the different ways of navigation search results.
# 3.2.5. page
- Type: Integer
- Required: False
Returns the current search results page. This field is returned only when the page selection
feature is enabled; see details.
See 3.1.7.
page
section section.
# 3.2.6. hitsPerPage
- Type: Integer
- Required: False
Returns the number of results per page. This field is returned only when the page selection
feature is enabled; see details.
See 3.1.7.
hitsPerPage
section section.
# 3.2.7. totalPages
- Type: Integer
- Required: False
Returns the total number of results pages. Calculated using [hitsPerPage
]. Both totalPages
and totalHits
are computed until they reach the pagination.maxTotalHits
number from the settings.
This field is returned only when the page selection
feature is enabled; see details.
# 3.2.8. totalHits
- Type: Integer
- Required: False
Returns the total number of search results. Both totalPages
and totalHits
are computed until they reach the pagination.maxTotalHits
number from the settings.
This field is returned only when the page selection
feature is enabled, see details.
# 3.2.9. facetDistribution
- Type: Object
- Required: False
Added to the search response when facets
is set for a search query. It contains the number of remaining candidates for each specified facet in the facets
search parameter.
If a field distributed as a facet contains no value, it is returned as a facetDistribution
field with an empty object as value.
See 3.1.4.
facets
section.
# 3.2.10. facetStats
- Type: Object
- Required: False
When using the facets
parameter, the distributed facets that contain some numeric values are displayed in a facetStats
object that contains, per facet, the numeric min
and max
values for that facet of all documents matching the search query.
If none of the hits returned by the search query have a numeric value for a facet, this facet is not part of the facetStats
object.
It ignores string values even if parseable. e.g "21"
isn't considered by the engine when computing the facetStats
min
and max
.
See 3.1.4.
facets
section.
# 3.2.11. processingTimeMs
- Type: Integer
- Required: True
Processing time of the search query in milliseconds.
# 3.2.12. query
- Type: String
- Required: True
- Default:
""
Query originating the response. Equals to the q
search parameter.
See 3.1.1.
q
section.
# 3.2.13. vector
EXPERIMENTAL
- Type: Array of Float
- Required: False
Vector query embedding originating the response. Equals to the vector
search parameter if specified.
See 3.1.18.
vector
# 2. Technical Details
n/a
# 3. Future Possibilities
- Add dedicated errors to replace
bad_request
error.
# 3.1. Formatting Search Results
- Replaces
_matchesPosition
with chars position instead of bytes. It could also be amode
to choosebyte
orchar
. - Move
attributesToHighlight
,highlightPreTag
,highlightPostTag
,attributesToCrop
,cropLength
andcropMarker
into aformatter
objet. - Add an option to only highlight complete query term.
- Expose the
formatter
resource as an index setting. - Highlight a phrase search as a single highlighted section.