ElasticSearch:过滤嵌套字段最小值并统计符合条件的竞赛数量
筛选所有用户得分均≥90分的竞赛并统计数量
一、筛选符合条件的竞赛
由于user_scores是嵌套字段,Elasticsearch无法直接判断数组内所有元素是否满足"得分≥90",我们可以用反向排除法:移除所有存在至少一位用户得分低于90分的竞赛,剩余的就是所有用户得分都达标的竞赛。
对应的查询语句:
GET /你的索引名/_search { "query": { "bool": { "must_not": [ { "nested": { "path": "user_scores", "query": { "range": { "user_scores.score": { "lt": 90 } } } } } ] } } }
must_not子句负责排除不符合要求的文档nested查询专门处理嵌套字段,指定path为user_scores后,在嵌套结构内查询是否存在score < 90的记录,只要有该竞赛就会被排除。
二、统计符合条件的竞赛数量
方式1:用Count API直接统计(效率最高)
如果只需要数量,不需要返回具体竞赛数据,直接用Count API:
GET /你的索引名/_count { "query": { "bool": { "must_not": [ { "nested": { "path": "user_scores", "query": { "range": { "user_scores.score": { "lt": 90 } } } } } ] } } }
返回结果里的count字段就是符合条件的竞赛总数。
方式2:结合聚合统计
如果需要在查询时同时返回聚合结果,用value_count聚合(前提是contest_name为唯一标识):
GET /你的索引名/_search { "size": 0, // 不返回具体文档,只输出聚合结果 "query": { "bool": { "must_not": [ { "nested": { "path": "user_scores", "query": { "range": { "user_scores.score": { "lt": 90 } } } } } ] } }, "aggs": { "达标竞赛数量": { "value_count": { "field": "contest_name.keyword" // 确保contest_name是keyword类型 } } } }
返回结果的aggregations.达标竞赛数量.value即为总数。
如果存在同名不同日期的竞赛,用composite聚合确保唯一计数:
GET /你的索引名/_search { "size": 0, "query": { "bool": { "must_not": [ { "nested": { "path": "user_scores", "query": { "range": { "user_scores.score": { "lt": 90 } } } } } ] } }, "aggs": { "唯一竞赛分组": { "composite": { "sources": [ {"竞赛名称": {"terms": {"field": "contest_name.keyword"}}}, {"竞赛日期": {"terms": {"field": "contest_date"}}} ] } }, "达标竞赛总数": { "bucket_script": { "buckets_path": { "count": "唯一竞赛分组._bucket_count" }, "script": "params.count" } } } }
这种方式会先按名称+日期分组,避免重复统计,最后通过bucket_script得到准确总数。
内容的提问来源于stack exchange,提问作者arkhamvm
相关产品推荐
相关产品推荐

