【问题标题】:Elastic search - Getting an overall status out of multiple records and then counting by status弹性搜索 - 从多条记录中获取整体状态,然后按状态计数
【发布时间】:2021-01-31 19:10:07
【问题描述】:

我正在使用 elasticsearch 来索引我的数据,看起来(有点)像这样:

[
 ...
 {"Name": "john",  "Part": "head",       "broken": true},
 {"Name": "john",  "Part": "shoulders",  "broken": false},
 {"Name": "john",  "Part": "knees",      "broken": false},
 {"Name": "john",  "Part": "toes",       "broken": false},
 {"Name": "steve", "Part": "head",       "broken": false},
 {"Name": "steve", "Part": "shoulders",  "broken": false},
 {"Name": "steve", "Part": "knees",      "broken": false},
 {"Name": "steve", "Part": "toes",       "broken": false}
 ...
]

现在我想以计数器的形式了解我的人的整体状态,显示有多少受伤,有多少没事。这里的名字作为指纹,这个人很好,如果他的任何部分都没有损坏:

People fine: 1
People hurt: 1

我尝试使用我对指标和存储桶聚合的(有限)知识,但无济于事。 现在我想知道:


是否甚至可以使用弹性搜索查询来获取此计数器?如果是,我该如何构造这样的查询?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    这个可以通过

    让我们选择后者。假设您在 Name 字段上有一个 .keyword 映射,您可以这样做:

    POST index_name/_search
    {
      "size": 0,
      "aggs": {
        "multibucket": {
          "filters": {
            "filters": {
              "placeholder": {
                "match_all": {}
              }
            }
          },
          "aggs": {
            "all_ppl_count": {
              "cardinality": {
                "field": "Name.keyword"
              }
            },
            "by_name": {
              "terms": {
                "field": "Name.keyword",
                "size": 100
              },
              "aggs": {
                "is_broken": {
                  "terms": {
                    "field": "broken",
                    "size": 2
                  }
                },
                "filter_fine_ppl": {
                  "bucket_selector": {
                    "buckets_path": {
                      "has_broken_something": "is_broken._bucket_count"
                    },
                    "script": "params.has_broken_something > 1"
                  }
                }
              }
            },
            "healthy_ppl_count": {
              "bucket_script": {
                "buckets_path": {
                  "all_ppl": "all_ppl_count",
                  "hurt_ppl": "by_name._bucket_count"
                },
                "script": "params.all_ppl - params.hurt_ppl"
              }
            }
          }
        }
      }
    }
    

    我们仅将 filters 聚合用作多桶占位符,使我们能够使用 bucket_* 管道聚合。之后就是:

    • 统计所有独特的人,
    • 根据姓名对人员进行分组,
    • is_broken 内部检查它们是否有任何损坏,如果有,则仅在by_name 聚合中保留其存储桶,以便以后可以使用总计数,
    • by_name 聚合的总体大小中减去破碎的人数,从而得到结果。

    然后响应将类似于以下内容:

    "aggregations" : {
      "multibucket" : {
        "buckets" : {
          "placeholder" : {
            "doc_count" : 8,
            "all_ppl_count" : {         <--
              "value" : 1
            },
            "by_name" : {
              "buckets" : [
                { ... }
              ]
            },
            "healthly_ppl_count" : {    <--
              "value" : 1.0
            }
          }
        }
      }
    }
    

    我们可以通过从all_ppl_count 中减去healthly_ppl_count 轻松获得“破碎人数”。

    【讨论】:

    • 我已经考虑过使用过滤器,但它并没有按照我想要的方式工作。它将把约翰算作 3 个破碎的人和 1 个好人。但事实上,他只是破碎了。即使将名称用作哈希并仅计算唯一的人,他也会显示为一个优秀的人和一个破碎的人......
    • 明白了。我误读了原来的问题。刚刚更新了一个实际答案。
    猜你喜欢
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多