下面的代码在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合并并在客户端内部化。这样做有很多原因,包括:
ArrayPool<T>
,Span<T>
等此更改意味着使用dynamic
作为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
}
}
没有铸造的工作解决方案可以如下。但是,它仅适用于字符串键值对。
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 row = new Dictionary<string, object>();
foreach (var keyValuePair in hit.Source)
{
var pair = keyValuePair.ToString().Split(':');
var key = pair[0].Replace("\"", "").Trim();
var value = pair[1].Replace("\"", "").Trim();
row[key] = value;
}
rows.Add(row);
}