多重搜索
/multi-search
路由允许您通过将多个搜索查询捆绑到一个 HTTP 请求中,在一个或多个索引上执行多个搜索查询。多重搜索也称为联邦搜索。
执行多重搜索
将多个搜索查询捆绑到一个 API 请求中。使用此端点一次搜索多个索引。
请求体
名称 | 类型 | 描述 |
---|---|---|
联合 | 对象 | 如果存在且不为 null ,则返回一个合并所有指定查询的搜索结果的列表 |
查询 | 对象数组 | 包含要执行的搜索查询列表。需要 indexUid 搜索参数,所有其他参数是可选的 |
警告
如果 Meilisearch 在处理多重搜索请求中的任何查询时遇到错误,它会立即停止处理请求并返回错误消息。返回的消息将仅针对遇到的第一个错误。
联合
使用 federation
来接收一个包含所有指定查询的搜索结果的列表,并按降序排列排名分数。 这称为联合搜索。
federation
可以选择包含以下参数
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
offset | 整数 | 0 | 要跳过的文档数量 |
limit | 整数 | 20 | 返回的最大文档数量 |
facetsByIndex | 数组对象 | null | 显示指定索引的 facet 信息 |
mergeFacets | 对象 | null | 显示指定索引的 facet 信息 |
如果 federation
缺失或为 null
,Meilisearch 将返回一个包含多个搜索结果对象的列表,列表中的每个项目对应于请求中的一个搜索查询。
facetsByIndex
facetsByIndex
必须是一个对象。它的键必须对应于您的 Meilisearch 项目中的索引。每个键必须与该索引的可过滤属性列表中的属性数组相关联
"facetsByIndex": {
"INDEX_A": ["ATTRIBUTE_X", "ATTRIBUTE_Y"],
"INDEX_B": ["ATTRIBUTE_Z"]
}
当您指定 facetsByIndex
时,多重搜索响应会包含一个额外的 facetsByIndex
字段。响应的 facetsByIndex
是一个对象,每个查询索引都有一个字段
{
"hits" [ … ],
…
"facetsByIndex": {
"INDEX_A": {
"distribution": {
"ATTRIBUTE_X": {
"KEY": <Integer>,
"KEY": <Integer>,
…
},
"ATTRIBUTE_Y": {
"KEY": <Integer>,
…
}
},
"stats": {
"KEY": {
"min": <Integer>,
"max": <Integer>
}
}
},
"INDEX_B": {
…
}
}
}
mergeFacets
mergeFacets
必须是一个对象,并且可以包含以下字段
maxValuesPerFacet
:必须是一个整数。如果指定,则表示单个 facet 返回的最大值数量。默认为分配给maxValuesPerFacet
索引设置的值
当 facetsByIndex
和 mergeFacets
都存在且不为 null 时,多重搜索响应中包含的 facet 信息将在所有查询索引中合并。响应会包含两个额外的字段:facetDistribution
和 facetStats
,而不是 facetsByIndex
{
"hits": [ … ],
…
"facetFederation": {
"ATTRIBUTE": {
"VALUE": <Integer>,
"VALUE": <Integer>
}
},
"facetStats": {
"ATTRIBUTE": {
"min": <Integer>,
"max": <Integer>
}
}
}
联合搜索的合并算法
联合搜索的合并结果将按排名分数降序返回。为了获得最终的结果列表,Meilisearch 将按照以下步骤进行比较
- 详细排名分数将按照以下方式对两个命中项进行标准化
- 连续相关性分数(与规则
words
、typo
、attribute
、exactness
或vector
相关)将为每个命中项组合成一个分数 sort
和geosort
分数细节保持不变
- 连续相关性分数(与规则
- 标准化后的详细排名分数将按字典顺序对两个命中项进行比较
- 如果两个命中项都有相关性分数,则分数较大的获胜。如果平分,则移动到下一步
- 如果一个结果有相关性分数或(地理)排序分数,Meilisearch 会选择它
- 如果两个结果在相同的排序方向上都有排序或地理排序分数,则 Meilisearch 将根据公共排序方向比较这些值。根据公共排序方向必须排在第一位的结果获胜。如果平分,则进入下一步
- 比较两个命中项的全局排名分数,以确定哪个排在第一位,忽略任何排序或地理排序
- 在完全平分的情况下,来自
queries
数组中排名最低的查询的文档优先。
不同的文档和联合搜索
如果满足以下条件,Meilisearch 会认为两个文档相同
- 它们来自同一个索引
- 并且它们的主键相同
无法指定应该将多个索引中的两个文档视为相同。
查询
queries
必须是一个对象数组。每个对象可以包含以下搜索参数
搜索参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
federationOptions | 对象 | null | 配置特定查询的联合设置 |
indexUid | 字符串 | N/A | 请求的索引的 uid |
q | 字符串 | "" | 查询字符串 |
offset | 整数 | 0 | 要跳过的文档数量 |
limit | 整数 | 20 | 返回的最大文档数量 |
hitsPerPage | 整数 | 1 | 每页返回的最大文档数 |
page | 整数 | 1 | 请求特定结果页面 |
filter | 字符串 | null | 按属性值过滤查询 |
facets | 字符串数组 | null | 显示每个 facet 的匹配计数 |
attributesToRetrieve | 字符串数组 | ["*"] | 要在返回的文档中显示的属性 |
attributesToCrop | 字符串数组 | null | 其值必须裁剪的属性 |
cropLength | 整数 | 10 | 裁剪值中的最大字数 |
cropMarker | 字符串 | "…" | 标记裁剪边界的字符串 |
attributesToHighlight | 字符串数组 | null | 突出显示属性中包含的匹配词 |
highlightPreTag | 字符串 | "<em>" | 插入到突出显示词语开头的字符串 |
highlightPostTag | 字符串 | "</em>" | 插入到突出显示词语结尾的字符串 |
showMatchesPosition | 布尔值 | false | 返回匹配词语的位置 |
sort | 字符串数组 | null | 按属性值排序搜索结果 |
matchingStrategy | 字符串 | last | 用于匹配文档中查询词语的策略 |
showRankingScore | 布尔值 | false | 显示文档的全局排名分数 |
attributesToSearchOn | 字符串数组 | ["*"] | 将搜索限制为指定的属性 |
除非另有说明,多重搜索查询的搜索参数与 /search
端点的搜索参数 功能完全相同。
limit
, offset
, hitsPerPage
和 page
这些选项与联合搜索不兼容。
federationOptions
federationOptions
必须是一个对象。它接受以下参数
weight
:作为此特定查询中搜索结果的排名分数的乘法因子。如果 <1.0
,则此查询的命中项不太可能出现在最终结果列表中。如果 >1.0
,则此查询的命中项更有可能出现在最终结果列表中。必须为正浮点数。默认为1.0
响应
对 /multi-search
查询的响应可能采用两种形式:联合和非联合。
非联合多重搜索请求
名称 | 类型 | 描述 |
---|---|---|
results | 对象数组 | 搜索查询的结果,与它们在请求中的顺序相同 |
每个搜索结果对象都由以下字段组成
名称 | 类型 | 描述 |
---|---|---|
indexUid | 字符串 | 请求的索引的 uid |
hits | 对象数组 | 查询的结果 |
offset | Number | 跳过的文档数 |
limit | Number | 要获取的文档数 |
estimatedTotalHits | Number | 匹配的估计总数 |
totalHits | Number | 匹配的详尽总数 |
totalPages | Number | 搜索结果页面的详尽总数 |
hitsPerPage | Number | 每页的结果数 |
page | Number | 当前搜索结果页面 |
facetDistribution | 对象 | 给定 facets 的分布 |
facetStats | 对象 | 每个 facet 的数字 min 和 max 值 |
processingTimeMs | Number | 查询的处理时间 |
query | 字符串 | 发起响应的查询 |
联合多重搜索请求
联合搜索请求返回单个对象和以下字段
名称 | 类型 | 描述 |
---|---|---|
indexUid | 字符串 | 请求的索引的 uid |
hits | 对象数组 | 查询的结果 |
offset | Number | 跳过的文档数 |
limit | Number | 要获取的文档数 |
estimatedTotalHits | Number | 匹配的估计总数 |
totalHits | Number | 匹配的详尽总数 |
totalPages | Number | 搜索结果页面的详尽总数 |
hitsPerPage | Number | 每页的结果数 |
page | Number | 当前搜索结果页面 |
facetDistribution | 对象 | 给定 facets 的分布 |
facetStats | 对象 | 每个 facet 的数字 min 和 max 值 |
processingTimeMs | Number | 查询的处理时间 |
query | 字符串 | 发起响应的查询 |
hits
数组中的每个结果都包含一个额外的 _federation
字段,其中包含以下字段
名称 | 类型 | 描述 |
---|---|---|
indexUid | 字符串 | 此文档的来源索引 |
queriesPosition | Number | 请求的 queries 数组中查询的数组索引号 |
示例
非联合多重搜索
curl \
-X POST 'https://127.0.0.1:7700/multi-search' \
-H 'Content-Type: application/json' \
--data-binary '{
"queries": [
{
"indexUid": "movies",
"q": "pooh",
"limit": 5
},
{
"indexUid": "movies",
"q": "nemo",
"limit": 5
},
{
"indexUid": "movie_ratings",
"q": "us"
}
]
}'
响应:200 Ok
{
"results":[
{
"indexUid":"movies",
"hits":[
{
"id":13682,
"title":"Pooh's Heffalump Movie",
…
},
…
],
"query":"pooh",
"processingTimeMs":26,
"limit":5,
"offset":0,
"estimatedTotalHits":22
},
{
"indexUid":"movies",
"hits":[
{
"id":12,
"title":"Finding Nemo",
…
},
…
],
"query":"nemo",
"processingTimeMs":5,
"limit":5,
"offset":0,
"estimatedTotalHits":11
},
{
"indexUid":"movie_ratings",
"hits":[
{
"id":"Us",
"director": "Jordan Peele",
…
}
],
"query":"Us",
"processingTimeMs":0,
"limit":20,
"offset":0,
"estimatedTotalHits":1
}
]
}
联合多重搜索
curl \
-X POST 'https://127.0.0.1:7700/multi-search' \
-H 'Content-Type: application/json' \
--data-binary '{
"federation": {},
"queries": [
{
"indexUid": "movies",
"q": "batman"
},
{
"indexUid": "comics",
"q": "batman"
}
]
}'
响应:200 Ok
{
"hits": [
{
"id": 42,
"title": "Batman returns",
"overview": …,
"_federation": {
"indexUid": "movies",
"queriesPosition": 0
}
},
{
"comicsId": "batman-killing-joke",
"description": …,
"title": "Batman: the killing joke",
"_federation": {
"indexUid": "comics",
"queriesPosition": 1
}
},
…
],
"processingTimeMs": 0,
"limit": 20,
"offset": 0,
"estimatedTotalHits": 2,
"semanticHitCount": 0
}