使用NEST API进行日期范围搜索以进行弹性搜索,返回不适当的结果

时间:2019-07-05 10:11:31

标签: c# elasticsearch nest

我正在尝试使用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#日期。

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

例如,由于我是欧洲中部时间,如果我给28.06.2019 14:48作为搜索起始日期,则应从28.06.2019 12:48开始搜索。或者,在“搜索到日期”中也应如此。

任何想法,我如何实现?

2 个答案:

答案 0 :(得分: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);
    }
}

希望有帮助。

答案 1 :(得分:0)

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

"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。

只需确保您同时使用“从”和“到”零件?在那种情况下,我认为第二个将覆盖第一个,并且应该合并为一个查询。

如果在ConnectionSettings中启用EnableDebugMode()(或使用client.RequestResponseSerializer.SerializeToString(...);手动序列化查询),则序列化查询的外观如何。 也许C#日期不符合预期?