【问题标题】:How do I count the number of buckets that match a condition in Elastic Search?如何计算与 Elastic Search 中的条件匹配的存储桶数?
【发布时间】:2021-02-16 05:22:57
【问题描述】:

我有一组描述用户分数的文档。同一个用户会有多个分数。

我的数据结构如下:

[
  { "user_id" : 3, "score" : 10 },
  { "user_id" : 1, "score" : 20 },
  { "user_id" : 2, "score" : 60 },
  { "user_id" : 1, "score" : 10 },
  ...
]

我正在尝试确定每个用户的最高分数。我使用的弹性搜索查询如下所示:

{
  "size": 0,
  "aggs": {
    "users": {
      "terms": {
        "field": "user_id",
        "size": 9999
      },
      "aggs": {
        "max_score": {
          "max": {
            "field": "score"
          }
        }
      }
    }
  }
}

响应如下所示:

  "aggregations": {
    "users": {
      "buckets": [
        {
          "key": "1",
          "doc_count": 10,
          "max_score": {
            "value": 10
          }
        },
        {
          "key": "2",
          "doc_count": 10,
          "max_score": {
            "value": 20
          }
        },
        ...
      ]
    }
  }
}

如何找到max_score > 20max_score > 50max_score > 100 所在的桶数?

有什么方法可以使响应如下所示?

  "aggregations": {
    "users": {
      "buckets": [
        {
          "key": "1",
          "doc_count": 10,
          "max_score": {
            "value": 10
          }
        },
        ...
      ],
      "scoresGreaterThan20": {
         "value": 10
      },
      "scoresGreaterThan50": {
         "value": 5
      },
      "scoresGreaterThan100": {
         "value": 2
      },
    }
  }
}

【问题讨论】:

    标签: elasticsearch kibana


    【解决方案1】:

    您可以通过重复相同的条款和最大聚合以及bucket selector aggregation 来实现您的用例,以满足您需要的不同条件。添加一个工作示例 -

    索引数据:

      { "user_id" : 3, "score" : 10 }
      { "user_id" : 1, "score" : 20 }
      { "user_id" : 2, "score" : 60 }
      { "user_id" : 1, "score" : 10 }
    

    搜索查询:

    执行桶选择器聚合后,您可以使用stats bucket aggregation 获取桶数。

    {
      "size": 0,
      "aggs": {
        "user_gt20": {
          "terms": {
            "field": "user_id",
            "size": 9999
          },
          "aggs": {
            "max_score": {
              "max": {
                "field": "score"
              }
            },
            "scoresGreaterThan20": {
              "bucket_selector": {
                "buckets_path": {
                  "values": "max_score"
                },
                "script": "params.values > 20"
              }
            }
          }
        },
        "user_gt20_count": {
          "stats_bucket": {
            "buckets_path": "user_gt20._count"
          }
        },
        "user_gt50": {
          "terms": {
            "field": "user_id",
            "size": 9999
          },
          "aggs": {
            "max_score": {
              "max": {
                "field": "score"
              }
            },
            "scoresGreaterThan50": {
              "bucket_selector": {
                "buckets_path": {
                  "values": "max_score"
                },
                "script": "params.values > 50"
              }
            }
          }
        },
        "user_gt50_count": {
          "stats_bucket": {
            "buckets_path": "user_gt50._count"
          }
        },
        "user_gt100": {
          "terms": {
            "field": "user_id",
            "size": 9999
          },
          "aggs": {
            "max_score": {
              "max": {
                "field": "score"
              }
            },
            "scoresGreaterThan100": {
              "bucket_selector": {
                "buckets_path": {
                  "values": "max_score"
                },
                "script": "params.values > 100"
              }
            }
          }
        },
        "user_gt100_count": {
          "stats_bucket": {
            "buckets_path": "user_gt100._count"
          }
        }
      }
    }
    

    搜索结果:

     "aggregations": {
        "user_gt100": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": []
        },
        "user_gt20": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": 2,
              "doc_count": 1,
              "max_score": {
                "value": 60.0
              }
            }
          ]
        },
        "user_gt50": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": 2,
              "doc_count": 1,
              "max_score": {
                "value": 60.0
              }
            }
          ]
        },
        "user_gt20_count": {
          "count": 1,            // note this
          "min": 1.0,
          "max": 1.0,
          "avg": 1.0,
          "sum": 1.0
        },
        "user_gt50_count": {
          "count": 1,             // note this
          "min": 1.0,
          "max": 1.0,
          "avg": 1.0,
          "sum": 1.0
        },
        "user_gt100_count": {
          "count": 0,             // note this
          "min": null,
          "max": null,
          "avg": null,
          "sum": 0.0
        }
      }
    

    【讨论】:

    • 谢谢,这就是我要找的。使用桶选择器后,有什么办法可以得到桶的数量吗?只是为了弄清楚有多少用户得分高于 x。
    • @EricWeiler 是的,您可以使用 stats 存储桶聚合来获取存储桶的数量,请查看更新后的搜索查询和结果,如果这能解决您的问题,请告诉我?
    猜你喜欢
    • 1970-01-01
    • 2022-11-30
    • 2021-02-17
    • 2013-06-19
    • 2018-06-28
    • 2021-10-11
    • 2019-06-17
    • 2017-10-30
    • 1970-01-01
    相关资源
    最近更新 更多