在Nest查询场景下如何将ES返回的Int时间戳转换为DateTime类型
报错原因与解决方案
报错原因
NEST默认将C#模型中的DateTime类型字段映射为Elasticsearch的date类型,序列化时期望获取ISO格式的时间字符串,而你的ES集群中CreatedTimeStamp字段存储的是毫秒级Unix时间戳的Long类型,类型不匹配触发JSON解析异常。
可行解决方案
方案1:模型字段添加
UnixTime特性(最常用)
直接在mdl.Event类的CreatedTimeStamp字段上添加NEST自带的UnixTime特性,NEST会自动完成Long时间戳和DateTime类型的互转,代码示例:public class Event { // 标记该字段为毫秒级Unix时间戳格式 [UnixTime] public DateTime CreatedTimeStamp { get; set; } // 其余字段定义... }若ES存储的是秒级时间戳,需显式指定单位:
[UnixTime(UnixTimeUnit.Second)]方案2:全局配置时间序列化规则
若所有DateTime类型字段在ES中均以时间戳格式存储,可在初始化NEST客户端时统一配置序列化规则,无需逐个修改字段特性:var settings = new ConnectionSettings(new Uri("你的ES集群访问地址")) .DefaultDateTimeInZone(DateTimeZone.Utc) // 建议指定UTC时区避免转换偏差 .DefaultDateFormat("epoch_millis"); // 配置默认时间格式为毫秒级时间戳 var client = new ElasticClient(settings);方案3:查询时通过脚本字段转换格式
若不方便修改模型或客户端配置,可在查询时新增脚本字段,将ES存储的Long类型时间戳转换为DateTime可识别的ISO格式字符串:var searchResponse = Event.client.Search<mdl.Event>(s => s .From(0) .Size(1000) .Query(q => q.MatchAll()) .ScriptFields(sf => sf .ScriptField("createdTimeStamp", sc => sc .Source("new Date(doc['created_time_stamp'].value).toISOString()") ) ) );
注意:所有时间转换建议统一按UTC时区处理后再按需转换为本地时区,避免出现时区偏移导致的时间错误。
内容的提问来源于stack exchange,提问作者Benjamin Salerno
相关产品推荐
相关产品推荐

