基于 Unix 时间戳的 Java 范围聚合

标签 java elasticsearch aggregation elasticsearch-aggregation

在我们的 elasticsearch(版本 2.3.1)索引中,每个文档都有一个 showDate 字段。该字段包含 unix 时间戳,我想找出过去 24 小时内有多少文档具有 showDate 以及过去 7 天内有多少文档具有 showDate

在我的 Java 代码中,我尝试这样做:

public static final String TODAY = "today";
public static final String THIS_WEEK = "thisWeek";
protected static final int SECONDS_PER_DAY = (24 * 60 * 60);

//...

Date now = new Date();
double timestampNow = now.getTime() / 1000;
double timestampYesterday = timestampNow - SECONDS_PER_DAY;
double timestampThisWeek = timestampNow - (SECONDS_PER_DAY * 7);
AbstractAggregationBuilder aggregation = AggregationBuilders.range("time").field("showDate")
                .addRange(TODAY, timestampYesterday, timestampNow)
                .addRange(THIS_WEEK, timestampThisWeek, timestampNow);
searchRequestBuilder.addAggregation(aggregation);

当我执行此搜索请求并查看生成的查询时,我得到类似这样的内容

{
  "from": 0,
  "size": 15,
  "query": {
      ...
  }
  "aggregations": {
    "time": {
      "range": {
        "field": "showDate",
        "ranges": [
          {
            "key": "today",
            "from": 1.465369290E9,
            "to": 1.465455690E9
          },
          {
            "key": "thisWeek",
            "from": 1.464850890E9,
            "to": 1.465455690E9
          }
        ]
      }
    }
  }
}

当我在 Kopf 等插件中执行查询时或Head我得到了预期的结果。当我在 java 服务中执行它时,docCount 始终为 0。

我注意到的唯一区别是插件将 double 值转换为 long 值。因此,在我发送查询后,1.465455690E9 数字将转换为 1465455690。有谁知道我如何在 Java 服务中获得与从插件获得相同的结果?

更新 1 感谢 Dimitris 的回答,我的代码如下所示。然而它仍然没有给出预期的结果。即使 Head 和 Kopf 告诉我有结果,DocCount 仍然始终为 0。

    Date now = new Date();
    long timestampNow = now.getTime() / 1000;
    long timestampYesterday = timestampNow - SECONDS_PER_DAY;
    long timestampThisWeek = timestampNow - (SECONDS_PER_DAY * 7);
    AbstractAggregationBuilder aggregation = AggregationBuilders.dateRange(KEY).field("showDate").format("epoch_second")
            .addRange(TODAY, timestampYesterday, timestampNow)
            .addRange(THIS_WEEK, timestampThisWeek, timestampNow);

更新 2: 我的最终解决方案如下所示:

Date now = new Date();
long timestampNow = now.getTime() / 1000;
long timestampYesterday = timestampNow - SECONDS_PER_DAY;
long timestampThisWeek = timestampNow - (SECONDS_PER_DAY * 7);
AbstractAggregationBuilder aggregation = AggregationBuilders.dateRange(KEY).field("showDate").format("epoch_second")
            .addRange(TODAY, String.valueOf(timestampYesterday), String.valueOf(timestampNow))
            .addRange(THIS_WEEK, String.valueOf(timestampThisWeek), String.valueOf(timestampNow))

此外,我还必须更改索引,以便 showDate 的类型为日期(格式仍然是 epoch_second)。

最佳答案

改用AggregationBuilders.dateRange。

在您的示例中:

...
AbstractAggregationBuilder aggregation = AggregationBuilders.dateRange("time").field("showData").format("epoch_second")
                                                            .addRange(TODAY, (long) timestampYesterday, (long) timestampNow)
                                                            .addRange(THIS_WEEK, (long) timestampThisWeek, (long) timestampNow);

请注意,您需要设置设置日期的格式,在您的情况下,“epoch_second”表示相应的elasticsearch内置格式(请参阅:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html#built-in-date-formats)

更新

事实证明时间戳必须作为字符串传入。因此代码变为:

...
AbstractAggregationBuilder aggregation = AggregationBuilders.dateRange("time").field("showData").format("epoch_second")
                                                            .addRange(TODAY, String.valueOf(timestampYesterday), String.valueOf(timestampNow))
                                                            .addRange(THIS_WEEK, String.valueOf(timestampThisWeek), String.valueOf(timestampNow));

关于基于 Unix 时间戳的 Java 范围聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37721156/

相关文章:

bash - Kibana错误/usr/local/bin/node:错误的选择:--no-warnings

elasticsearch - Elasticsearch:聚合准确性

java - 从 Java 7 转换为 6,Matcher.group

java - 将字节数组打印到热敏打印机Java

elasticsearch - 尝试使用 docker-compose 设置 Elasticsearch 集群

elasticsearch - 在过滤后的 elasticSearch 查询中使用 minimum_should_match

javascript - 如果 Angular 正在做......从 Selenium 中检测东西

java - 在 Java/Clojure 中生成包含使用 OpenType 功能的文本的图像

arrays - 如何仅在 Mongoose 中使用聚合来填充嵌套在对象数组中的字段?

elasticsearch - 在 ElasticSearch 5.6.3 中获取嵌套文档的聚合导致 Lucene 异常