【问题标题】:Elastic search range dates弹性搜索范围日期
【发布时间】:2013-12-20 13:56:04
【问题描述】:

我从 Mongo 数据库创建了一个弹性搜索索引。 Mongo中的文档结构如下:

{
    "_id" : ObjectId("525facace4b0c1f5e78753ea"),
    "time" : ISODate("2013-10-17T09:23:56.131Z"),
    "type" : "A",
    "url" : "www.google.com",
    "name" : "peter",
}

索引的创建(显然)没有任何问题。 现在,我正在尝试使用 Elastic Search 在两个日期之间检索索引中的文档。我读过我必须使用范围查询,但我已经尝试了很多次,比如

MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "peter").type(Type.PHRASE).minimumShouldMatch("99%");
LocalDateTime toLocal = new LocalDateTime(2013,12,18, 0, 0);
Date to = toLocal.toDate();
LocalDateTime fromLocal = new LocalDateTime(2013,12,17, 0, 0);
Date from = fromLocal.toDate();
RangeQueryBuilder queryDate = QueryBuilders.rangeQuery("time").to(to).from(from);
FilterBuilder filterDate = FilterBuilders.queryFilter(queryDate);       

srb = esH.client.prepareSearch("my_index");
srb.setQuery(queryBuilder);
srb.setFilter(filterDate);
sr = srb.execute().actionGet();

虽然应该有很多结果,但我得到了 0 次点击。我尝试输入字符串而不是日期,但结果相同。

当我执行没有过滤器的基本查询时,例如:

MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "peter").type(Type.PHRASE).minimumShouldMatch("99%");

SearchRequestBuilder srb = esH.client.prepareSearch("my_index");
rb.setQuery(queryBuilder);
SearchResponse sr = srb.execute().actionGet();

我喜欢这样的样子:

{
"_index" : "my_index",
"_type" : "type",
"_id" : "5280d3c2e4b05e95aa703e34",
"_score" : 1.375688, "_source" : {"type":["A"],"time":["Mon Nov 11 13:55:30 CET 2013"],"name":["peter"]}
}

time 字段不再具有 ISODate("2013-10-17T09:23:56.131Z") 格式。

总而言之,考虑到格式,用于在两个日期(和时间)之间查询的 Java 代码(和类型)是什么?

【问题讨论】:

  • 您能否添加构建器正在生成的实际 JSON 查询?如果没有看到 ES 实际看到的内容,真的很难说发生了什么。

标签: java elasticsearch


【解决方案1】:

您可能在这一行将错误的字段名称传递给范围查询:

RangeQueryBuilder queryDate = QueryBuilders.rangeQuery("time").to(to).from(from);

应该是@timestamp(或您用来存储时间戳的字段)而不是time。此外,对于您包含的示例文档,Elasticsearch 中似乎没有 time 字段。这也指出了 time 字段未正确从 Mongo 转换为 Elasticsearch 的问题。

【讨论】:

    【解决方案2】:

    你可以试试

    FilterBuilders.rangeFilter("@timestamp").from("from time").to("toTime")
    

    【讨论】:

    • 这是弃用还是什么?因为它不起作用。
    【解决方案3】:

    这会起作用 -

    您可以将长时间戳传递给 gte 和 lte 参数。

    QueryBuilders.rangeQuery("time").gte(startTime).lte(endTime);

    确保在 startTime 和 endTime 的末尾添加一个“L”,以便它知道它是 long 而不是 int。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      • 2019-01-08
      相关资源
      最近更新 更多