【问题标题】:ElasticSearch: Retrieving the latest document for a given timestampElasticSearch:检索给定时间戳的最新文档
【发布时间】:2015-08-06 14:12:40
【问题描述】:

我有一个 ElasticSearch 数据库,其中包含一些文档。每个文档都有自己的时间戳字段。

我目前有一个需要两个时间戳的 WebApi,startTimeendTime。 WebApi 只是在 ES 上执行查询以获取时间戳在给定范围内的文档。

这是我当前的查询:

    var readRecords = ElasticClient.Search<SegmentRecord>(s => s
        .Index(ElasticIndexName)
        .Filter(f =>
            f.Range(i =>
                i.OnField(a => a.DateTime).GreaterOrEquals(startTime).LowerOrEquals(endTime))).Size(MaximumNumberOfReturnedDocs).SortAscending(p => p.DateTime)).Documents;

很简单,基本上就是基于startTimeendTime参数的范围查询。它有效。 :-)

现在的问题是:我什至需要检索时间戳低于startTime 的最新文档。 所以基本上最终的查询应该是:

  • [startTime,endTime]范围内的所有文档

  • 具有时间戳startTime的最新时间文档

第一部分显然可以返回任意数量的记录,零,一个或多个

第二部分应该只返回一个文档,(如果在starTime 之前不存在任何文档,则返回零)

【问题讨论】:

  • 我认为您要么需要两个查询,要么保留当前查询的 0 个或多个文档列表,并添加一个聚合部分,您可以在其中获得“及时的最新文档”。然后,在尝试了解您返回的内容时,您需要查看 hits 部分和 aggs 部分。
  • 谢谢!拜托,你能详细说明你的答案吗?

标签: c# elasticsearch asp.net-web-api web-applications nosql


【解决方案1】:

我在上面的评论中的意思是这样的:

{
  "query": {
    "filtered": {
      "filter": {
        "range": {
          "time": {
            "gte": "2015-06-04",
            "lte": "2015-06-05"
          }
        }
      }
    }
  },
  "aggs": {
    "global_all_docs_agg": {
      "global": {},
      "aggs": {
        "filter_for_min": {
          "filter": {
            "range": {
              "time": {
                "lte": "2015-06-04"
              }
            }
          },
          "aggs": {
            "min_date": {
              "top_hits": {
                "size": 1,
                "sort": [
                  {
                    "time": "asc"
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
}

结果如下:

      "hits": [
         {
            "_index": "sss",
            "_type": "test",
            "_id": "1",
            "_score": 1,
            "_source": {
               "time": "2015-06-05"
            }
         },
         {
            "_index": "sss",
            "_type": "test",
            "_id": "2",
            "_score": 1,
            "_source": {
               "time": "2015-06-04"
            }
         },
         {
            "_index": "sss",
            "_type": "test",
            "_id": "4",
            "_score": 1,
            "_source": {
               "time": "2015-06-05"
            }
         }
      ]
   },
   "aggregations": {
      "global_all_docs_agg": {
         "doc_count": 6,
         "filter_for_min": {
            "doc_count": 4,
            "min_date": {
               "hits": {
                  "total": 4,
                  "max_score": null,
                  "hits": [
                     {
                        "_index": "sss",
                        "_type": "test",
                        "_id": "5",
                        "_score": null,
                        "_source": {
                           "time": "2015-06-01"
                        },
                        "sort": [
                           1433116800000
                        ]
                     }
                  ]
               }
            }
         }
      }
   }

startTimeendTime 之间的列表位于 hits 下。低于startTime 的最小值在aggregations 之下。

【讨论】:

  • 似乎有一个问题。聚合将只返回最小值,而不是匹配最小值的整个文档。
  • 其实我找到了办法。我更新了答案中的查询。解决方案是将min 聚合替换为top_hits + sort 聚合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-27
  • 1970-01-01
相关资源
最近更新 更多