DateRange 搜索在 Elastic 搜索 NEST 中不起作用 api
DateRange search is not working in Elastic search NEST api
我有 table 条日志记录,我想按日期进行简单搜索。
例如,我想搜索 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
}
}
}
}
}
}
}
}
我将 post 我们在评论中得出的答案作为答案,因为我认为有几件事可以改进以提高性能和可读性。
解决方案:
问题中的查询使用 .Field(f => 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.
希望对您有所帮助。
我有 table 条日志记录,我想按日期进行简单搜索。
例如,我想搜索 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
}
}
}
}
}
}
}
}
我将 post 我们在评论中得出的答案作为答案,因为我认为有几件事可以改进以提高性能和可读性。
解决方案:
问题中的查询使用 .Field(f => 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.
希望对您有所帮助。