【问题标题】:Date Range search using NEST api for elastic search returning inappropriate results使用 NEST api 进行弹性搜索的日期范围搜索返回不适当的结果
【发布时间】:2019-07-07 17:26:46
【问题描述】:

我正在尝试使用 NEST API 在弹性搜索中使用日期范围搜索。

我知道 ES 在与 Nlog 集成时将时间戳存储在 UTC 中。 但是,我需要在此 @timestamp 字段中进行日期范围搜索。

我写了以下查询:

从日期搜索:

qcd.DateRange(r => r
                    .Field(f => f.timestamp)
                    .GreaterThanOrEquals(searchFromDateTime)
                    .TimeZone("+02:00")
                );

迄今为止的搜索:

qcd.DateRange(r => r
                        .Field(f => f.timestamp)
                        .LessThanOrEquals(searchToDateTime)
                        .TimeZone("+02:00")
                    );

这是查询的其余部分:

searchResponse = (SearchResponse<SearchEventDto>)client.Search<SearchEventDto>(s => s
                    .Index("logstash-*")
                    .Type("logevent")
                    .Query(q => qcd)
                );

SearchFromDateTime 或 SearchToDateTime 是 c# 日期。

显然,查询中有问题,因为它没有考虑时差。

例如,由于我是 CET 时间,如果我将 28.06.2019 14:48 作为搜索起始日期,它应该从 28.06.2019 12:48 开始搜索。或者,Search To date 中也应该发生同样的情况。

任何想法,我怎么能做到这一点?

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    我已经为您准备了一个工作示例,也许您可​​以在您的案例中找到它的问题。如果没有,请使用您希望在查询中找到的示例文档更新问题。

    class Program
    {
        public class Document  
        {
            public int Id { get; set; }
            public DateTime Timestamp { get; set; }
        } 
    
        static async Task Main(string[] args)
        {
            var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
            var connectionSettings = new ConnectionSettings(pool);
            connectionSettings.DefaultIndex("documents");
    
            //only for debbuging purpose, don't use in production
            connectionSettings.DisableDirectStreaming();
            connectionSettings.PrettyJson();
    
            var client = new ElasticClient(connectionSettings);
    
            await client.Indices.DeleteAsync("documents");
            await client.Indices.CreateAsync("documents");
    
            var response = await client.IndexAsync(
                new Document {Id = 1, Timestamp = new DateTime(2010, 01, 01, 10, 0, 0)}, descriptor => descriptor);
    
            var searchResponse = await client.SearchAsync<Document>(s => s
                .Query(q => q
                    .Bool(b => b
                        //I'm using date range in filter context as I don't want elasticsearch
                        //to calculate score for each document found,
                        //should be faster and likely it will be cached
                        .Filter(f =>
                            f.DateRange(dt => dt
                                .Field(field => field.Timestamp)
                                .LessThanOrEquals(new DateTime(2010, 01, 01, 11, 0, 0))
                                .TimeZone("+1:00"))))));
    
            //prints 1
            Console.WriteLine(searchResponse.Documents.Count);
        }
    }
    

    希望对您有所帮助。

    【讨论】:

    • 谢谢罗伯。我已经找到了解决方案(忘记在这里更新:P)。再次感谢,这是完美的答案!我有一个问题。我看到您正在使用 SearchAsync 进行搜索。 SearchAsync 会提高性能吗?我知道这与我上面提出的问题不同。但是,如果您能帮助我理解它,那就太好了:)
    • 是的,它有助于利用线程池,所以当我们等待来自 elasticsearch 的响应时,系统可以决定将这个阻塞的线程用于其他事情。如果您想了解有关 async/await 的更多信息,我建议您阅读 Async in C# 5.0 书或查看作者的博客(我目前找不到 :))。
    • 感谢 Rob 的回答!
    【解决方案2】:

    理论上,它应该是这样工作的。以下弹性查询

    "query": {
        "range": {
            "publication_date": {
                "gte": "2012-05-29T01:00:00",
                "lte": "2012-05-29T01:00:00", 
                "time_zone": "+01:00"
            }
        }
    }
    

    给我文件,结果是 2012-05-29T00:00:00。

    只是为了确定一下,您是否同时使用 From 和 To 部分?在这种情况下,我相信第二个会覆盖第一个,应该合并到一个查询中。

    如果您在 ConnectionSettings 中启用 EnableDebugMode()(或使用 client.RequestResponseSerializer.SerializeToString(...); 手动序列化查询),序列化查询会是什么样子。 可能c#日期不符合预期?

    【讨论】:

      猜你喜欢
      • 2020-07-21
      • 2019-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-01
      相关资源
      最近更新 更多