使用NEST 6.0为Elasticsearch枚举动态命中结果

问题描述 投票:3回答:2

下面的代码在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的有效转换,或者此代码块的其他解决方案?

c# elasticsearch nest enumeration
2个回答
4
投票

使用NEST 6.x,对Json.NET的依赖是IL合并并在客户端内部化。这样做有很多原因,包括:

  • 在将NEST合并到已经使用Json.NET的其他项目中时,消除了对Json.NET的依赖性,从而避免了与主要版本的冲突。
  • 在应用于NEST类型的序列化约定与您自己的类型可能具有的任何约定之间创建明确的边界
  • 奠定基础,以便在未来查看替代的序列化库/技术,例如异步流,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
    }
}

0
投票

没有铸造的工作解决方案可以如下。但是,它仅适用于字符串键值对。

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);
 }
© www.soinside.com 2019 - 2024. All rights reserved.