【问题标题】:Elasticsearch Date histogram aggregation without considering yearElasticsearch 不考虑年份的日期直方图聚合
【发布时间】:2020-10-08 10:42:10
【问题描述】:

我想聚合关于月份和日期的数据,我正在尝试使用日期直方图聚合,但它正在考虑完整的日期对象。

我有如下数据:

      {
          "created" : "2020-09-26",
          "id" : 6,
          "name" : "Halum khamu"      
      },
      {
          "created" : "2021-09-26",
          "id" : 7,
          "name" : "new new"
      },
      {
          "created" : "2020-10-07",
          "id" : 8,
          "name" : "Halum new"
      }

我正在使用这个查询:

GET /regulations/_search/
{
  "aggs": {
    "news_over_time": {
      "date_histogram": {
        "field": "created",
        "calendar_interval": "day",
        "keyed": true,
        "format": "yyy-MM-dd",
        "min_doc_count": 1
      }
    }
  }
}

它为我返回的数据:

      "buckets" : {
        "2020-09-26" : {
          "key_as_string" : "2020-09-26",
          "key" : 1600300800000,
          "doc_count" : 1
        },
        "2021-09-26" : {
          "key_as_string" : "2021-09-26",
          "key" : 1601337600000,
          "doc_count" : 1
        },
        "2020-10-07" : {
          "key_as_string" : "2020-10-07",
          "key" : 1632873600000,
          "doc_count" : 1
        }
      }

但我的预期产出将不考虑年份:

      "buckets" : {
        "09-26" : {
          "key_as_string" : "09-26",
          "key" : 1600300800000,
          "doc_count" : 2
        },
        "10-07" : {
          "key_as_string" : "10-07",
          "key" : 1632873600000,
          "doc_count" : 1
        }
      }

我该怎么做?

【问题讨论】:

    标签: elasticsearch elasticsearch-dsl elasticsearch-dsl-py


    【解决方案1】:

    没有直接的方法可以解决这个问题,但这应该可以完成工作:

    GET regulations/_search
    {
      "size": 0,
      "aggs": {
        "day_histogram": {
          "scripted_metric": {
            "init_script": "state.day_map = [:];",
            "map_script": """
              def created = doc.created.value;
              
              def month = created.getMonthOfYear();
              def day = created.getDayOfMonth();
              
              def key = String.format('%02d', new def[] { month })  
                        + '-' + 
                        String.format('%02d', new def[] { day });
              
              if (state.day_map.containsKey(key)) {
                state.day_map[key] += 1;
              } else {
                state.day_map[key] = 1;
              }
            """,
            "combine_script": "return state.day_map",
            "reduce_script": "return states"
          }
        }
      }
    }
    

    屈服

    {
      ...
      "aggregations":{
        "day_histogram":{
          "value":[
            {
              "09-26":2,
              "10-07":1
            }
          ]
        }
      }
    }
    

    编辑——实际上有一个更简单的方法:

    GET regulations/_search
    {
      "size": 0,
      "aggs": {
        "day_histogram": {
          "terms": {
            "script": {
              "source": "doc.created.value.monthOfYear + '-' + doc.created.value.dayOfMonth"
            },
            "size": 10
          }
        }
      }
    }
    

    【讨论】: