我正在尝试从kibana_sample_data_flights索引中获取一组包含时间戳的数据。运行查询时,ElasticSearch可以正确识别它并返回结果,但是会崩溃,
无效的日期时间格式。价值:2019-06-03T
上
Elasticsearch.Net.Utf8Json.Formatters.ISO8601DateTimeFormatter.Deserialize(JsonReader&reader,IJsonFormatterResolver formatterResolver)
第一次,我以为是我的对象被错误地索引,只是排除了结果,但是我在另一个条目上遇到了相同的错误。使用Kibana进行搜索可以正常工作,时间戳为 2019年6月2日@ 20:00:00.000 ,这很有意义,因为我位于UTC-5区域。
如何让NEST / ElasticSearch.net正确识别日期?
-编辑1:按要求提供弹性版本和示例代码。
我正在使用NEST和ElasticSearch.Net v7.0.0。 ElasticSearch版本请求返回
{
"name" : "M79539",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "CxG9dTeSTsudlhJBGiVmJQ",
"version" : {
"number" : "7.1.0",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "606a173",
"build_date" : "2019-05-16T00:43:15.323135Z",
"build_snapshot" : false,
"lucene_version" : "8.0.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
如果有帮助,这里是程序
class Program
{
static void Main(string[] args)
{
//Kibana: http://m79539:5601/app/kibana#/home?_g=()
// NEST
var settings = new ConnectionSettings(new Uri("http://m79539:9200/"))
.DefaultIndex("kibana_sample_data_flights")
.DefaultFieldNameInferrer(p => p);
var client = new ElasticClient(settings);
var scrollTimeout = "5m";
var scrollSize = 1000;
var initialResponse = client.Search<FlightDetail>(s => s
.From(0).Take(scrollSize)
.Query(q => +q
.DateRange(r => r
.Field(f => f.Timestamp)
.GreaterThan(DateMath.Anchored(new DateTime(2019,06,01)))
.LessThan(DateMath.Now)) && +!q
.Term(p => p.FlightNum, "59H86EL")
)
.Scroll(scrollTimeout)
//scroll is optimized for this sort and we will sort in our own code
.Sort(ss => ss.Ascending(SortSpecialField.DocumentIndexOrder))
);
var results = new List<FlightDetail>();
if (!initialResponse.IsValid || string.IsNullOrEmpty(initialResponse.ScrollId))
throw new Exception(initialResponse.ServerError.Error.Reason);
if (initialResponse.Documents.Any())
results.AddRange(initialResponse.Documents);
string scrollid = initialResponse.ScrollId;
bool isScrollSetHasData = true;
while (isScrollSetHasData)
{
ISearchResponse<FlightDetail> loopingResponse = client.Scroll<FlightDetail>(scrollTimeout, scrollid);
if (loopingResponse.IsValid)
{
results.AddRange(loopingResponse.Documents);
scrollid = loopingResponse.ScrollId;
}
isScrollSetHasData = loopingResponse.Documents.Any();
}
client.ClearScroll(new ClearScrollRequest(scrollid));
foreach (var result in results){
Console.WriteLine($"{result.Timestamp} | {result.FlightNum} | {result.FlightDelayMin}");
}
}
}
public class FlightDetail
{
public string FlightNum { get; set; }
public int FlightDelayMin { get; set; }
public object Source { get; set; }
[Nest.Text(Name = "timestamp")]
public DateTime Timestamp { get; set; }
}
有问题的结果(在我的安装中)是548
{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAANizsWaTdsY3ViS2hUR2FyRHZESmdKeVRWZw==",
"took": 1,
"timed_out": false,
"terminated_early": true,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 9227,
"relation": "eq"
},
"max_score": null,
"hits": [{
"_index": "kibana_sample_data_flights",
"_type": "_doc",
"_id": "1Lr3DmsBoDCXrrhScXCk",
"_score": null,
"_source": {
"FlightNum": "86C3GQY",
"DestCountry": "MX",
"OriginWeather": "Sunny",
"OriginCityName": "Rome",
"AvgTicketPrice": 395.9230418749486,
"DistanceMiles": 6362.054220749258,
"FlightDelay": false,
"DestWeather": "Damaging Wind",
"Dest": "Licenciado Benito Juarez International Airport",
"FlightDelayType": "No Delay",
"OriginCountry": "IT",
"dayOfWeek": 0,
"DistanceKilometers": 10238.733787837495,
"timestamp": "2019-06-03T",
"DestLocation": {
"lat": "19.4363",
"lon": "-99.072098"
},
"DestAirportID": "AICM",
"Carrier": "JetBeats",
"Cancelled": false,
"FlightTimeMin": 602.2784581080879,
"Origin": "Leonardo da Vinci - Fiumicino Airport",
"OriginLocation": {
"lat": "41.8002778",
"lon": "12.2388889"
},
"DestRegion": "MX-DIF",
"OriginAirportID": "FCO",
"OriginRegion": "SE-BD",
"DestCityName": "Mexico City",
"FlightTimeHour": 10.037974301801464,
"FlightDelayMin": 0
},
"sort": [4379]
}]
}
}
---编辑2:基于@Rob命题的简单代码示例。以相同的问题结束。我添加了try / catch以便能够消除错误,然后查看Fiddler中遇到的情况。
private static void SimpleSample()
{
var client = new ElasticClient(new Uri("http://m79539:9200"));
for (var i = 0; ; i++)
{
try
{
var results = client.Search<SampleData>(s => s
.Index("kibana_sample_data_flights")
.From(i * 10)
.Query(q => q.MatchAll()));
foreach (var document in results.Documents)
{
Console.WriteLine(document.Timestamp.ToString("f") + "|" + document.FlightNum);
}
}
catch (Elasticsearch.Net.UnexpectedElasticsearchClientException ex)
{
Console.WriteLine(ex.Message);
}
}
}
private class SampleData
{
public DateTime Timestamp { get; set; }
[Nest.Text(Name = "FlightNum")]
public string FlightNum { get; set; }
}
答案 0 :(得分:0)
这是示例应用程序,可以从kibana_sample_data_flights索引中检索时间戳数据。
class Program
{
static void Main(string[] args)
{
var client = new ElasticClient(new Uri("http://localhost:9200"));
var results = client.Search<SampleData>(s => s
.Index("kibana_sample_data_flights").Query(q => q.MatchAll()));
foreach (var document in results.Documents)
{
Console.WriteLine(document.Timestamp.ToString("f"));
}
}
}
internal class SampleData
{
public DateTime Timestamp { get; set; }
}
产生以下输出:
Monday, 17 June 2019 00:00
Monday, 17 June 2019 18:27
Monday, 17 June 2019 17:11
Monday, 17 June 2019 10:33
Monday, 17 June 2019 05:13
Monday, 17 June 2019 01:43
Monday, 17 June 2019 13:49
Monday, 17 June 2019 04:54
Monday, 17 June 2019 12:09
Monday, 17 June 2019 12:09
在该示例中,由于default field name convention being used,NEST能够正确地将SampleData属性Timestamp
映射到索引的字段timestamp
。
更新
确实存在解析ID为1Lr3DmsBoDCXrrhScXCk
z且值为“ timestamp”:“ 2019-06-03T”的文档的错误日期值的问题。
我们可以在定义ConnectionSettings
对象时通过自定义序列化来处理错误,并在遇到错误时继续执行:
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings =
new ConnectionSettings(pool,
sourceSerializer: (builtin, settings) => new JsonNetSerializer(
builtin, settings,
() => new JsonSerializerSettings {Error = HandlerError}
));
var client = new ElasticClient(connectionSettings);
private static void HandlerError(object sender, ErrorEventArgs e)
{
//handle error the way you like
e.ErrorContext.Handled = true;
}
现在我们得到以下输出:
..
Wednesday, 19 June 2019 21:39
Thursday, 20 June 2019 04:47
Thursday, 20 June 2019 21:51
Thursday, 20 June 2019 02:27
..
您可以在NEST here中阅读有关配置序列化过程的更多信息。
希望有帮助。