【问题标题】:DateRange search is not working in Elastic search NEST apiDateRange 搜索在弹性搜索 NEST api 中不起作用
【发布时间】:2019-07-03 23:27:03
【问题描述】:

我有一个日志记录表,我想按日期进行简单的搜索。

例如,我想搜索 01.06.2019 00:00:00 (mm.DD.yyyy hh:mm:ss) 之前的所有查询,我写了这个查询:

var query = client.Search<SearchEventDto>(s => s
                .AllIndices()
                .AllTypes()
                .Query(q => q
                    .MatchAll() && +q
                    .DateRange(r =>r
                        .Field(f => f.timestamp)
                        .LessThanOrEquals(new DateTime(2019,06,01, 0, 0, 0))
                    )
                )
            ); 

我的 Dto 如下所示:

 public class SearchEventDto : IDto
    {
        [KendoColumn(Hidden = true, Editable = true)]
        public string id { get; set; }

        [KendoColumn(Order = 2, DisplayName = "Level")]
        public string level { get; set; }
        [KendoColumn(Order = 4, DisplayName = "Message")]
        public string message { get; set; }

        [KendoColumn(Hidden = true)]
        public string host { get; set; }
        [KendoColumn(Order = 3, DisplayName = "Source")]
        public string src { get; set; }

        [KendoColumn(Order = 1, DisplayName = "Timestamp", UIType = UIType.DateTime)]
        public DateTime timestamp { get; set; }

        [KendoColumn(Hidden = true)]
        public DateTime time { get; set; }

    }

不幸的是,它返回所有记录而不过滤任何内容。 我哪里错了?

提前致谢!

PS:ES 版本:6.7.0,NEST:6.8

PS:我已将日志与 Nlog 集成。因此,现在它每天都会插入一个以日期为名称的新索引。这是 219-06-28 的映射(我使用的是@timestamp):

{
    "logstash-2019-06-28": {
        "mappings": {
            "logevent": {
                "properties": {
                    "@timestamp": {
                        "type": "date"
                    },
                    "host": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "level": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "message": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "src": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "time": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    }
                }
            }
        }
    }
}

【问题讨论】:

  • 您使用的是哪个版本的 elasticsearch 和 NEST?你能分享一下索引映射吗?
  • ES 6.7.0, NEST 6.8
  • 您好,我是弹性搜索的新手,如何获取索引映射?再次感谢您的回复:)
  • 对,所以问题出在 elasticsearch 中,您有 @timestamp,但您将 timestamp 与 NEST(.Field(f =&gt; f.timestamp)) 一起传递。尝试更改为.Field("@timestamp"),或者您可以使用Date 属性标记SearchEventDto.timestamp。您可以在docs 阅读更多相关信息。
  • @Rob 你最后的评论应该是一个答案:)

标签: c# elasticsearch nest


【解决方案1】:

我将发布我们在 cmets 中发现的内容作为答案,因为我认为有几件事可以改进以提高性能和可读性。

解决方案:

问题中的查询使用了.Field(f =&gt; f.timestamp),NEST 将其翻译为使用timestamp 字段而不是@timestamp。对.Field("@timestamp") 进行简单更改即可解决问题,因为这是索引映射中的正确字段名称。

{
    "logstash-2019-06-28": {
        "mappings": {
            "logevent": {
                "properties": {
                    "@timestamp": {
                        "type": "date"
                    },
                    ..
                }
            }
        }
    }
}

我们还可以使用PropertyName 属性标记timestamp 属性,以告诉NEST 使用@timestamp 作为名称而不是timestamp

 public class SearchEventDto : IDto
    {
        [KendoColumn(Order = 1, DisplayName = "Timestamp", UIType = UIType.DateTime)]
        [PropertyName("@timestamp")]
        public DateTime timestamp { get; set; }

    }

并查询

var query = client.Search<SearchEventDto>(s => s
                .AllIndices()
                .AllTypes()
                .Query(q => q
                    .MatchAll() && +q
                    .DateRange(r =>r
                        .Field(f => f.timestamp)
                        .LessThanOrEquals(new DateTime(2019,06,01, 0, 0, 0))
                    )
                )
            ); 

也可以正常工作。

改进:

仅查询特定索引:

var query = client.Search<SearchEventDto>(s => s
        .AllIndices()
        .AllTypes()
        ..

通过使用AllIndices(),我们告诉elasticsearch 尝试从所有索引中收集文档,我们可以稍作更改以仅查询带有日志数据的索引:

var query = client.Search<SearchEventDto>(s => s
                .Index("logstash-*")
                .Type("logevent")
                ..

为日期范围过滤器使用过滤器上下文:

.Query(q => q.Bool(b => b.Filter(f => f.DateRange(..))))

这样您的查询应该会更快,因为它不关心计算搜索相关性得分。你可以阅读更多关于它的信息here

希望对您有所帮助。

【讨论】:

  • 另外,非常感谢关于索引的额外提示 :) :)
猜你喜欢
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
相关资源
最近更新 更多