如何在elasticsearch中创建一个考虑日期范围的直方图

问题

我有以下架构中的数据:

{
  start_date: '2017-01-01',
  end_date: '2017-01-05',
},
{
  start_date: '2017-01-03',
  end_date: '2017-01-07',
}

我正在尝试每天创建一个直方图,如果特定文档的开始日期和结束日期日期重叠在那一天,我会给出.

有了这些数据,输出桶将是:

{
  "2017-01-01": { "doc_count": 1 },
  "2017-01-02": { "doc_count": 1 },
  "2017-01-03": { "doc_count": 2 },
  "2017-01-04": { "doc_count": 2 },
  "2017-01-05": { "doc_count": 2 },
  "2017-01-06": { "doc_count": 1 },
  "2017-01-07": { "doc_count": 1 }
}

在阅读了所有的elasticsearch聚合文档之后,我看不出这是怎么回事.任何帮助表示赞赏.

根据Olivier的回答,我做了以下几点:

创建辅助函数以生成开始日期和结束日期之间的所有包含天数:

const generateDateRange = (start, end) => {
  const startDate = moment(start);
  const endDate = moment(end);

  const range = [];

  const date = startDate;
  while (date.isSameOrBefore(endDate)) {
    range.push(date.format('YYYY-MM-DD'));
    date.add(1, 'day');
  }

  return range;
};

创建了一个辅助函数,根据日期范围生成聚合所需的所有过滤器:

const generateActivityFilters = (range, options = {}) => {
  const filters = {};

  range.map((date) => {
    filters[date] = {
      bool: {
        filter: [
          { range: { [options.start]: { lte: date } } },
          { range: { [options.end]: { gte: date } } },
        ],
      },
    };
    return true;
  });

  return filters;
};

最后,运行查询如下:

{
  "size": 0, 
  "aggs": {
    "date_histo": {
      "filters": {
        "filters": filters // from generateActivityFilters
      }
    }
  }
}

我看到的唯一替代方法是在脚本中进行整个操作,但是在使用弹性搜索脚本几个小时后,我放弃了这种方法.

最佳答案 我发现这个问题非常有趣.

个人搜索没有带来合理的方法来实现这一点,其中一个原因是你如何定义日期直方图的开始和结束日期(因为它通常使用字段参数来计算这个)?

使用存储桶和管道聚合的更高级的人可能会提供帮助,但我最接近的将是“欺骗”并构建过滤器聚合以实现目标:

{
  "size": 0, 
  "aggs": {
    "date_histo": {
      "filters": {
        "filters": {
          "2017-01-01": {
            "bool": {
              "filter": [
                {"range": {"start_date": {"lte": "2017-01-01"}}},
                {"range": {"end_date": {"gte": "2017-01-01"}}}
              ]
            }
          },
          "2017-01-02": {
            "bool": {
              "filter": [
                {"range": {"start_date": {"lte": "2017-01-02"}}},
                {"range": {"end_date": {"gte": "2017-01-02"}}}
              ]
            }
          },
          ...
        }
      }
    }
  }
}

不是很漂亮,但可能仍然值得考虑作为更好答案的起点.

点赞