尝试使用时间戳字段按范围过滤数据。查询如下:
var scanResults = await _elasticClient.SearchAsync<OemCatalogModel>(s => s.Index(indexName)
.Source(sf => sf
.Includes(i => i
.Fields(
f => f.Event,
f => f.MemberId,
f => f.IsInternalUser,
f => f.IndexName,
f => f.IsMobile,
f => f.VinNumber,
f => f.Timestamp
)
)
)
.Query(q => q.Range(p => p.Field<Timestamp>(t=>t.Timestamp)
.GreaterThanOrEquals(sd)
.LessThanOrEquals(ed)
))
.Size(10000).Scroll("60s"));
startDate
和 endDate
从 DatePicker 获取为 DateTimeOffset 并初始化 sd
和 ed
,如下所示:
var sd = startDate.Value.ToUnixTimeSeconds();
var ed = endDate.Value.ToUnixTimeSeconds();
时间戳字段在映射模型中看起来如下
[Date(Name = "timestamp")]
public Int64 Timestamp { get; set; }
此查询引发了“parse_exception”异常:
"reason" : {
"type" : "parse_exception",
"reason" : "failed to parse date field [1.6540308E9] with format [epoch_second]: [failed to parse date field [1.6540308E9] with format [epoch_second]]",
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "failed to parse date field [1.6540308E9] with format [epoch_second]",
"caused_by" : {
"type" : "date_time_parse_exception",
"reason" : "date_time_parse_exception: Failed to parse with all enclosed parsers"
}
}
}
NEST 生成的 ElasticSearch 查询如下所示:
{“查询”:{“范围”:{“时间戳”:{“gte”:1654030800.0,“lte”:1654203599.0}}},“大小”:10000,“_source”:{“包括”:[ "事件","member_id","is_internal_user","indexName","is_mobile","vin_number","时间戳"]}}
此过滤器不起作用,因为添加了范围参数
.0
。我检查了这个,没有.0
,它是有效的。例如 _source
的结果如下所示:
"_source" : {
"member_id" : 69500,
"is_mobile" : false,
"event" : "close_unit_card",
"is_internal_user" : false,
"timestamp" : 1654066236
}
如何使用时间戳正确映射范围过滤器?也许我必须使用
DataRange
?如果是,如何将 sd
和 ed
转换为 ElasticSearch 中使用的时间戳?
还尝试执行以下操作,但出现不同的异常:
查询如下:
.Query(q => q.DateRange(p => p.Field(t=>t.Timestamp)
.GreaterThanOrEquals(DateTime.Parse(startDate.Value.ToString()))
.LessThanOrEquals(DateTime.Parse(endDate.Value.ToString()))))
出现以下异常:
"reason" : {
"type" : "parse_exception",
"reason" : "failed to parse date field [2022-05-31T21:00:00Z] with format [epoch_second]: [failed to parse date field [2022-05-31T21:00:00Z] with format [epoch_second]]",
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "failed to parse date field [2022-05-31T21:00:00Z] with format [epoch_second]",
"caused_by" : {
"type" : "date_time_parse_exception",
"reason" : "date_time_parse_exception: Failed to parse with all enclosed parsers"
}
}
}
奇怪的解决方案但有效:
初始化开始和结束日期:
var sd = startDate.Value.ToUnixTimeSeconds();
var ed = endDate.Value.ToUnixTimeSeconds();
日期范围看起来像:
.Query(q => q.DateRange(p => p.Field(t=>t.Timestamp).Format("epoch_second")
.GreaterThanOrEquals(sd)
.LessThanOrEquals(ed)
))
模型看起来像:
[Date(Format = DateFormat.epoch_second, Name = "timestamp")]
public DateTime Timestamp { get; set; }
通过 DateRange,您可以使用 DateTime 结构:
var searchResponse = client.Search<_Source>(s => s
.Query(q => q
.Bool(b => b
.Filter(fi => fi
.DateRange(r => r
.Field(f => f.timestamp) // Replace with your actual timestamp field
.GreaterThanOrEquals(new DateTime(2023, 11, 17, 12, 05, 0)) // Start time
.LessThanOrEquals(new DateTime(2023, 11, 17, 12, 10, 0)) // End time
)
)
.Must(fi => fi
.Term(t => t
.Field(f => f.host.name) // Replace with your actual host name field
.Value("evp-lwsj101")
)
)
)
)
.From(0)
.Size(100) // adjust the size based on your needs
);