下面的代码在Nest 6.0之前适用于枚举动态匹配结果.但是它不再抛出InvalidCastException.
码:
var response = elasticClient.Search<dynamic>(
s => s.Query(q => q.QueryString(m => m.Query(elasticQueryModel.QueryString))
).Source(src => src.Includes(f => f.Fields(fields))).Size(querySize).AllTypes().Index(elasticQueryModel.Index));
var hits = response.Hits;
var rows = new List<Dictionary<string, object>>();
foreach (var hit in hits)
{
var source = (IDictionary<string, Newtonsoft.Json.Linq.JToken>)hit.Source;
var row = new Dictionary<string, object>();
foreach (var keyValuePair in source)
{
row[keyValuePair.Key] = keyValuePair.Value;
}
rows.Add(row);
}
什么是hit.Source的有效转换,或此代码块的另一种解决方案?
解决方法:
使用NEST 6.x,对Json.NET的依赖关系被IL合并并在客户端内部化.这样做的原因有很多,其中包括:
>消除对Json.NET的依赖,从而避免在将NEST合并到已经使用Json.NET的其他项目中时与主要版本发生冲突.
>在应用于NEST类型的序列化约定与您自己的类型可能具有的约定之间创建清晰的界限
>为将来研究替代序列化库/技术奠定基础.异步流,ArrayPool T,Span T等.
这种变化意味着使用动态作为Search< T>()上的通用类型将不再像Json.NET的JObject一样返回源文档,而是作为内部类型Nest.Json.Linq.JObject的实例返回.
如果您仍想将Json.NET与NEST结合使用,那么还有NEST.JsonNetSerializer nuget package允许您使用plug in your own serialization based on Json.NET.(由于NEST 6.x尚未发布GA,因此文档仍在进行中).
虽然我认为这里更简单的方案是使用Dictionary< string,object>作为Search< T>()的通用参数
var response = client.Search<Dictionary<string, object>>(s => s
.Query(q => q
.QueryString(m => m
.Query("username")
)
)
.AllTypes()
);
foreach (var hit in response.Hits)
{
foreach (var keyValuePair in hit.Source)
{
// do something
}
}