Elasticsearch 术语或基数聚合 - 按不同值的数量排序

标签 elasticsearch aggregation cardinality

friend ,

我正在做一些分析,以从数以百万计的文档中找到独特的对。模拟示例如下所示:

文档字段1字段2

  1. AAA : BBB
  2. AAA:CCC
  3. PPP : QQQ
  4. PPP : QQQ
  5. XXX : YYY
  6. XXX : YYY
  7. 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/

相关文章:

elasticsearch - 为什么我在Elastic search中看到已删除的文档

sql - 具有复合主键的表的基数不好

SQL - 外键约束和基数

mongodb - Mongodb 聚合管道对嵌套数组对象值进行排序

mysql - 使用返回两个值的子查询时违反基数

search - 稀疏文档的多个索引或多个映射类型?

elasticsearch - 带有脚本的 Elasticsearch 聚合提供了异常(exception)

java - Elasticsearch5.x flink 连接器中的 NoSuchMethodError

mysql - MySQL中如何计算解析时间?

sql - 在 mysql 中聚合结果时选择最新的字符串