【问题标题】:Elasticsearch get unique field count only once in a date rangeElasticsearch 在一个日期范围内仅获取一次唯一字段计数
【发布时间】:2020-03-30 09:22:27
【问题描述】:

我有一个案例,我需要提取在给定时间段内多次出现的用户(user_id)。我创建了一个聚合,我可以在其中提取和计算它们在一段时间内出现的实例,但它们应该在下一个日期左右再次计算,它应该只出现一次。

这就像计算给定时间段的唯一用户注册,您只需要计算他们出现的第一个实例/日期。日期过滤器可以是每小时、每天、每周、每月。

 user_id_1   2020-01-05
 user_id_1   2020-02-06
 user_id_1   2020-02-14
 user_id_2   2020-02-03
 user_id_2   2020-02-04
 user_id_3   2020-03-03
 user_id_1   2020-03-15
 user_id_2   2020-03-21
 user_id_3   2020-03-25
 user_id_3   2020-04-01

预期的输出应该是,在他们第一次出现的月份只计算一次。他们不应该在其他月份再次计算

user_id_1 | 1 count | 2020-01-05
user_id_2 | 1 count | 2020-02-03
user_id_3 | 1 count | 2020-03-03
Total     | 3 counts|

这是我想出的示例代码。它计算在给定时间段内出现的 user_ids 的实例。

{
   "size":0,
   "aggs":{
      "result":{
         "date_range":{
            "field":"timestamp",
            "format":"yyyy-MM-dd",
            "ranges":[
               {
                  "from":"2020-01-01",
                  "to":"2020-03-31"
               }
            ]
         },
         "aggs":{
            "histogram":{
               "date_histogram":{
                  "field":"timestamp",
                  "calendar_interval":"1M",
                  "extended_bounds":{
                     "min":"2020-01-01",
                     "max":"2020-03-31"
                  },
                  "format":"yyyy-MM-dd"
               },
               "aggs":{
                  "user_sigups":{
                     "terms":{
                        "field":"user_id.keyword"
                     }
                  }
               }
            }
         }
      }
   }
}

上述查询的示例结果如下所示。

{
   "histogram":{
      "buckets":[
         {
            "key_as_string":"2020-01-01",
            "key":1577836800000,
            "doc_count":1925,
            "user_sigups":{
               "doc_count_error_upper_bound":0,
               "sum_other_doc_count":328,
               "buckets":[
                  {
                     "key":"2532456443539602",
                     "doc_count":505
                  }
               ]
            }
         }
      ]
   }
}

任何帮助将不胜感激。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您需要使用基数聚合来计算唯一项目和最小聚合以获得最小日期

    查询:

    {
      "size": 0,
      "aggs": {
        "result": {
          "date_range": {
            "field": "timestamp",
            "format": "yyyy-MM-dd",
            "ranges": [
              {
                "from": "2020-01-01",
                "to": "2020-03-31"
              }
            ]
          },
          "aggs": {
            "histogram": {
              "date_histogram": {
                "field": "date",
                "interval": "1M",
                "extended_bounds": {
                  "min": "2020-01-01",
                  "max": "2020-03-31"
                },
                "format": "yyyy-MM-dd"
              },
              "aggs": {
                "user_sigups": {
                  "terms": {
                    "field": "user_id.keyword"
                  },
                 "aggs": {
                   "unique_count": {
                     "cardinality": {
                       "field": "user_id.keyword"
                     }
                   },
                   "min_date":{
                     "min": {
                       "field": "timestamp"
                     }
                   }
                 }
                }
              }
            }
          }
        }
      }
    }
    

    结果:

    "aggregations" : {
        "result" : {
          "buckets" : [
            {
              "key" : "2020-01-01-2020-03-31",
              "from" : 1.5778368E12,
              "from_as_string" : "2020-01-01",
              "to" : 1.5856128E12,
              "to_as_string" : "2020-03-31",
              "doc_count" : 9,
              "histogram" : {
                "buckets" : [
                  {
                    "key_as_string" : "2020-01-01",
                    "key" : 1577836800000,
                    "doc_count" : 1,
                    "user_sigups" : {
                      "doc_count_error_upper_bound" : 0,
                      "sum_other_doc_count" : 0,
                      "buckets" : [
                        {
                          "key" : "user_id_1",
                          "doc_count" : 1,
                          "min_date" : {
                            "value" : 1.5781824E12,
                            "value_as_string" : "2020-01-05"
                          },
                          "unique_count" : {
                            "value" : 1
                          }
                        }
                      ]
                    }
                  },
                  {
                    "key_as_string" : "2020-02-01",
                    "key" : 1580515200000,
                    "doc_count" : 4,
                    "user_sigups" : {
                      "doc_count_error_upper_bound" : 0,
                      "sum_other_doc_count" : 0,
                      "buckets" : [
                        {
                          "key" : "user_id_1",
                          "doc_count" : 2,
                          "min_date" : {
                            "value" : 1.5809472E12,
                            "value_as_string" : "2020-02-06"
                          },
                          "unique_count" : {
                            "value" : 1
                          }
                        },
                        {
                          "key" : "user_id_2",
                          "doc_count" : 2,
                          "min_date" : {
                            "value" : 1.580688E12,
                            "value_as_string" : "2020-02-03"
                          },
                          "unique_count" : {
                            "value" : 1
                          }
                        }
                      ]
                    }
                  },
                  {
                    "key_as_string" : "2020-03-01",
                    "key" : 1583020800000,
                    "doc_count" : 4,
                    "user_sigups" : {
                      "doc_count_error_upper_bound" : 0,
                      "sum_other_doc_count" : 0,
                      "buckets" : [
                        {
                          "key" : "user_id_3",
                          "doc_count" : 2,
                          "min_date" : {
                            "value" : 1.5831936E12,
                            "value_as_string" : "2020-03-03"
                          },
                          "unique_count" : {
                            "value" : 1
                          }
                        },
                        {
                          "key" : "user_id_1",
                          "doc_count" : 1,
                          "min_date" : {
                            "value" : 1.5842304E12,
                            "value_as_string" : "2020-03-15"
                          },
                          "unique_count" : {
                            "value" : 1
                          }
                        },
                        {
                          "key" : "user_id_2",
                          "doc_count" : 1,
                          "min_date" : {
                            "value" : 1.5847488E12,
                            "value_as_string" : "2020-03-21"
                          },
                          "unique_count" : {
                            "value" : 1
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        }
    

    告诉我它是如何为你工作的

    【讨论】:

    • 我已经编辑了这个问题,以明确输出应该是什么。我的最终结果应该就像计算给定时间段的唯一用户注册。一旦 user_id 在特定日期出现,则不应再次计算。这甚至可能吗?
    • 我认为我上面的代码也是如此。你能运行它并给我它未能更好地理解问题的文档
    • 尝试运行代码的结果是,user_id_1 在 1 月被计算一次,然后在 2 月再次计算。应该在哪里 user_id_1 只会在 1 月被计算,然后永远不会自 1 月统计后的其他月份再次出现。
    • 你将不得不处理这个客户端。没有办法在该存储桶中获得 min date global 和 min date in interval 。所以这个检查必须在客户方
    • 是的,我想这是唯一的方法。感谢您的洞察力,@jaspreet
    猜你喜欢
    • 1970-01-01
    • 2019-12-04
    • 2014-03-08
    • 2018-03-13
    • 1970-01-01
    • 2016-07-31
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多