我有一张日志记录表,我想按日期进行简单搜索。
例如,我想搜索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
}
}
}
}
}
}
}
}
我将在评论中找到的内容作为答案发布,因为我认为可以进行一些改进以提高性能和可读性。
解:
从问题中查询使用的.Field(f => f.timestamp)
是NEST翻译的,而timestamp
不是使用字段@timestamp
。进行简单更改即可.Field("@timestamp")
解决问题,因为这是索引映射中的正确字段名称。
{
"logstash-2019-06-28": {
"mappings": {
"logevent": {
"properties": {
"@timestamp": {
"type": "date"
},
..
}
}
}
}
}
我们也可以timestamp
用PropertyName
属性标记属性以告诉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(..))))
这样,您的查询应该会更快,因为它无需考虑计算搜索相关性得分。您可以在此处了解更多信息。
希望能有所帮助。
完美的答案。罗布行得通!
另外,非常感谢索引的额外提示:) :)