friend ,
我正在做一些分析,以从数以百万计的文档中找到独特的对。模拟示例如下所示:
文档字段1字段2
- AAA : BBB
- AAA:CCC
- PPP : QQQ
- PPP : QQQ
- XXX : YYY
- XXX : YYY
- MMM : NNN
文档的 90% 包含一个独特的对,如上面文档 3、4、5、6 和 7 中所示,我对我的聚合结果不感兴趣。我有兴趣汇总文档 1 和 2。
词条聚合查询:
"aggs": { "f1": { "terms": { "field": "FIELD1", "min_doc_count": 2 }, "aggs": { "f2": { "terms": { "field": "FIELD2" } } } } }
术语聚合结果
"aggregations": { "f1": { "buckets": [ { "key": "PPP", "doc_count": 2, "f2": { "buckets": [ { "key": "QQQ", "doc_count": 2 } ] } }, { "key": "XXX", "doc_count": 2, "f2": { "buckets": [ { "key": "YYY", "doc_count": 2 } ] } }, { "key": "AAA", "doc_count": 2, "f2": { "buckets": [ { "key": "BBB", "doc_count": 1 }, { "key": "CCC", "doc_count": 1 } ] } } ] } }
我只对聚合结果中的键 AAA 感兴趣。过滤包含不同对的聚合结果的最佳方法是什么?
我尝试使用基数聚合,这会导致不一致的值计数。但是,我无法从聚合结果中过滤掉我不感兴趣的内容。
基数聚合查询
"aggs": { "f1": { "terms": { "field": "FIELD1", "min_doc_count": 2 }, "aggs": { "f2": { "cardinality": { "field": "FIELD2" } } } } }
基数聚合结果
"aggregations": { "f1": { "buckets": [ { "key": "PPP", "doc_count": 2, "f2": { "value" : 1 } }, { "key": "XXX", "doc_count": 2, "f2": { "value" : 1 } }, { "key": "AAA", "doc_count": 2, "f2": { "value" : 2 } } ] } }
至少,如果我可以按基数排序,那将有助于我找到一些解决方法。请在这方面帮助我。
P.S:编写一个 spark/mapreduce 程序来后处理/过滤聚合结果并不是这个问题的预期解决方案。
最佳答案
我建议将过滤器查询与聚合一起使用,因为您只对 field1=AAA 感兴趣。
我这里有一个类似的例子。
例如,我有一个我医院所有病人的索引。我将他们的药物使用情况存储在一个嵌套对象 DRUG 中。每个病人可以服用不同的药物,也可以多次服用一种药物。
现在如果我想找到至少服用一次阿司匹林的患者人数,查询可以是:
{
"size": 0,
"_source": false,
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"nested": {
"path": "DRUG",
"filter": {
"bool": {
"must": [{ "term": { "DRUG.NAME": "aspirin" } }]
}}}}}},
"aggs": {
"DRUG_FACETS": {
"nested": {
"path": "DRUG"
},
"aggs": {
"DRUG_NAME_FACETS": {
"terms": { "field": "DRUG.NAME", "size": 0 },
"aggs": {
"DISTINCT": { "cardinality": { "field": "DRUG.PATIENT" } }
}
}}}}
}
示例结果:
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 0,
"hits": []
},
"aggregations": {
"DRUG_FACETS": {
"doc_count": 11,
"DRUG_NAME_FACETS": {
"buckets": [
{
"key": "aspirin",
"doc_count": 6,
"DISTINCT": {
"value": 6
}
},
{
"key": "vitamin-b",
"doc_count": 3,
"DISTINCT": {
"value": 2
}
},
{
"key": "vitamin-c",
"doc_count": 2,
"DISTINCT": {
"value": 2
}
}
]
}
}
}
}
桶中的第一个是阿司匹林。但是你可以看到另外2位患者在服用阿司匹林的同时也服用了维生素b。
如果您将 DRUG.NAME 的字段值更改为另一个药物名称,例如“vitamin-b”,我想您会在桶的第一个位置获得 vitamin-b。
希望对您的问题有所帮助。
关于Elasticsearch 术语或基数聚合 - 按不同值的数量排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25649255/