折叠搜索结果
collapse
参数按特定字段值对搜索结果进行分组。这只会返回每个组中的顶部文档,有助于通过消除重复项来减少冗余。
collapse
参数要求被折叠的字段类型为 keyword
或 numeric
。
折叠搜索结果
要使用数据填充索引,请定义索引映射并将 item
字段索引为 keyword
类型。以下示例请求展示了如何定义索引映射、填充索引,然后搜索它。
定义索引映射
PUT /bakery-items
{
"mappings": {
"properties": {
"item": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"price": {
"type": "float"
},
"baked_date": {
"type": "date"
}
}
}
}
填充索引
POST /bakery-items/_bulk
{ "index": {} }
{ "item": "Chocolate Cake", "category": "cakes", "price": 15, "baked_date": "2023-07-01T00:00:00Z" }
{ "index": {} }
{ "item": "Chocolate Cake", "category": "cakes", "price": 18, "baked_date": "2023-07-04T00:00:00Z" }
{ "index": {} }
{ "item": "Vanilla Cake", "category": "cakes", "price": 12, "baked_date": "2023-07-02T00:00:00Z" }
搜索索引,返回所有结果
GET /bakery-items/_search
{
"query": {
"match": {
"category": "cakes"
}
},
"sort": ["price"]
}
此查询返回未折叠的搜索结果,显示所有文档,包括“巧克力蛋糕”的两个条目。
搜索索引并折叠结果
要按 item
字段对搜索结果进行分组并按 price
排序,您可以使用以下查询
折叠后的 item
字段搜索结果
GET /bakery-items/_search
{
"query": {
"match": {
"category": "cakes"
}
},
"collapse": {
"field": "item"
},
"sort": ["price"]
}
响应
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "bakery-items",
"_id": "mISga5EB2HLDXHkv9kAr",
"_score": null,
"_source": {
"item": "Vanilla Cake",
"category": "cakes",
"price": 12,
"baked_date": "2023-07-02T00:00:00Z",
"baker": "Baker A"
},
"fields": {
"item": [
"Vanilla Cake"
]
},
"sort": [
12
]
},
{
"_index": "bakery-items",
"_id": "loSga5EB2HLDXHkv9kAr",
"_score": null,
"_source": {
"item": "Chocolate Cake",
"category": "cakes",
"price": 15,
"baked_date": "2023-07-01T00:00:00Z",
"baker": "Baker A"
},
"fields": {
"item": [
"Chocolate Cake"
]
},
"sort": [
15
]
}
]
}
}
折叠后的搜索结果将只显示一个“巧克力蛋糕”条目,这表明 collapse
参数如何减少冗余。
collapse
参数仅影响顶部搜索结果,不改变任何聚合结果。响应中显示的总命中数反映了应用参数之前的所有匹配文档,包括重复项。但是,响应不指示操作形成的唯一组的确切数量。
展开折叠结果
您可以使用 inner_hits
属性展开每个折叠的顶部命中。
以下示例请求应用 inner_hits
来检索每种蛋糕的最低价格和最新商品
GET /bakery-items/_search
{
"query": {
"match": {
"category": "cakes"
}
},
"collapse": {
"field": "item",
"inner_hits": [
{
"name": "cheapest_items",
"size": 1,
"sort": ["price"]
},
{
"name": "newest_items",
"size": 1,
"sort": [{ "baked_date": "desc" }]
}
]
},
"sort": ["price"]
}
每个折叠命中的多个内部命中
要为每个折叠结果获取多个内部命中组,您可以为每个组设置不同的条件。例如,让我们请求每个烘焙食品的三个最新项目
GET /bakery-items/_search
{
"query": {
"match": {
"category": "cakes"
}
},
"collapse": {
"field": "item",
"inner_hits": [
{
"name": "cheapest_items",
"size": 1,
"sort": ["price"]
},
{
"name": "newest_items",
"size": 3,
"sort": [{ "baked_date": "desc" }]
}
]
},
"sort": ["price"]
}
此查询在 cakes
类别中搜索文档,并按 item_name
字段对搜索结果进行分组。对于每个 item_name
,它检索价格最低的三个项目和最新的三个项目,按 baked_date
降序排序。
您可以通过为响应中每个折叠命中对应的每个内部命中请求发送一个附加查询来展开组。如果组或内部命中请求过多,这可能会显著降低过程速度。max_concurrent_group_searches
请求参数可用于控制此阶段允许的最大并发搜索数。默认值基于数据节点数量和默认搜索线程池大小。