如何在AWS OpenSearch中统计多字段组合的唯一键总数?
解决方案
方案一:预处理生成唯一组合字段(推荐,性能最优)
既然多字段组合是唯一标识,最直接的方式是在写入文档时新增一个拼接字段,比如unique_key,值为search_term|category1|category2|category3(选一个不会出现在字段值里的分隔符,避免冲突)。
1. 自动生成组合字段
可以用OpenSearch的 ingest pipeline 自动生成该字段,无需修改业务代码:
PUT _ingest/pipeline/generate_unique_key { "description": "Generate unique key from search_term and categories", "processors": [ { "join": { "field": ["search_term", "category1", "category2", "category3"], "separator": "|", "target_field": "unique_key" } } ] }
后续写入文档时指定pipeline即可:
PUT your_index/_doc/1?pipeline=generate_unique_key { "category1":"AD", "category2":"GOOGLE", "category3":"SEARCH", "search_term":"SAMSUNG TV", "report_date":20230919 }
2. 查询获取结果
现在可以用cardinality直接统计总唯一键数,用composite聚合获取每个组合的最新report_date:
{ "size": 0, "query": { "bool": { "should": [ { "match": { "search_term": { "operator": "and", "query": "SAMSUNG TV" } } } ], "minimum_should_match": 1 } }, "aggs": { "total_count": { "cardinality": { "field": "unique_key.keyword" } }, "unique_combinations": { "composite": { "size": 1000, "sources": [ { "search_term": { "terms": { "field": "search_term.keyword" } } }, { "category1": { "terms": { "field": "category1" } } }, { "category2": { "terms": { "field": "category2" } } }, { "category3": { "terms": { "field": "category3" } } } ] }, "aggs": { "latest_report_date": { "max": { "field": "report_date" } } } } } }
返回结果会包含total_count(唯一键总数)和unique_combinations.buckets(每个组合的信息及最新日期),可直接转换为你需要的格式。
方案二:查询时动态生成组合(无需修改索引)
如果无法修改索引结构,可以用脚本字段在查询时动态拼接组合值,再结合聚合实现需求,但注意:数据量较大时,脚本会带来性能损耗。
查询示例
{ "size": 0, "query": { "bool": { "should": [ { "match": { "search_term": { "operator": "and", "query": "SAMSUNG TV" } } } ], "minimum_should_match": 1 } }, "aggs": { "total_count": { "cardinality": { "script": { "source": "doc['search_term.keyword'].value + '|' + doc['category1'].value + '|' + doc['category2'].value + '|' + doc['category3'].value" } } }, "unique_combinations": { "composite": { "size": 1000, "sources": [ { "search_term": { "terms": { "field": "search_term.keyword" } } }, { "category1": { "terms": { "field": "category1" } } }, { "category2": { "terms": { "field": "category2" } } }, { "category3": { "terms": { "field": "category3" } } } ] }, "aggs": { "latest_report_date": { "top_hits": { "size": 1, "_source": ["report_date"], "sort": [{"report_date": "desc"}] } } } } } }
total_count通过脚本拼接字段生成唯一值,用cardinality统计总数;unique_combinations用composite聚合获取所有组合,同时通过top_hits拿到每个组合的最新report_date;- 如果组合数量超过
size,可以用composite聚合的after参数分页获取剩余桶。
内容的提问来源于stack exchange,提问作者HB HONG
相关产品推荐
相关产品推荐

