如何在聚合中组合match filter,实现Post文档指定筛选与条数限制?
实现方案(Elasticsearch 7.x+ 适用)
核心逻辑是保证20条IsHomePage: true的文档全量返回,再从80条IsTagged: true的文档中随机取30条合并,两种常用实现方式如下:
方案1:聚合拆分查询
通过两个独立的过滤聚合分别抓取两类数据,结果明确可拆分,适合需要单独处理两类文档的场景:
- 第一组聚合过滤所有
IsHomePage: true的文档,直接返回全部20条 - 第二组聚合过滤
IsTagged: true且IsHomePage: false的文档,随机排序后取前30条 - 合并两组结果刚好得到50条符合要求的文档
POST /post/_search { "size": 0, "aggs": { "homepage_docs": { "filter": { "term": { "IsHomePage": true } }, "aggs": { "all_homepage": { "top_hits": { "size": 20, "_source": ["Title", "IsHomePage", "IsTagged"] } } } }, "tagged_docs": { "filter": { "bool": { "must": [ { "term": { "IsTagged": true } }, { "term": { "IsHomePage": false } } ] } }, "aggs": { "random_tagged": { "top_hits": { "size": 30, "_source": ["Title", "IsHomePage", "IsTagged"], "sort": [ { "_script": { "type": "number", "script": "Math.random()", "order": "asc" } } ] } } } } } }
查询返回后提取aggregations.homepage_docs.all_homepage.hits.hits和aggregations.tagged_docs.random_tagged.hits.hits两个数组合并即可。
方案2:单查询加权排序
无需聚合,通过自定义排序权重一次返回50条结果,实现更简洁:
给所有IsHomePage: true的文档设置远高于随机值的固定排序权重,保证它们全部排在结果最前面,剩余位置由随机排序的IsTagged: true文档填充。
POST /post/_search { "size": 50, "query": { "bool": { "should": [ { "term": { "IsHomePage": true } }, { "term": { "IsTagged": true } } ] } }, "sort": [ { "_script": { "type": "number", "script": { "source": "doc['IsHomePage'].value ? 100 : Math.random()" }, "order": "desc" } } ] }
内容的提问来源于stack exchange,提问作者user1765862
相关产品推荐
相关产品推荐

