你能用NEST 2从InnerHits获得强力击球吗?

时间:2016-07-09 08:16:31

标签: elasticsearch nest

我正在使用NEST 2客户端对我们的Elasticsearch执行查询。

我们有一个查询来查询嵌套文档数组,并使用.InnerHits()在结果中包含嵌套文档的匹配项。

有没有办法强制将InnerHits的结果输入到特定的POCO类而不是动态访问结果字段?

1 个答案:

答案 0 :(得分:5)

是的; Here's an example from the integration tests for inner hits;对于任何可以返回内部命中的搜索,原则都是相同的

public interface IRoyal
{
    string Name { get; set; }
}


[ElasticsearchType(IdProperty = "Name")]
public abstract class RoyalBase<TRoyal> : IRoyal
    where TRoyal : class, IRoyal
{
    public string Name { get; set; }
}

public class King : RoyalBase<King>
{
    public List<King> Foes { get; set; }
}

public class Prince : RoyalBase<Prince> { }
public class Duke : RoyalBase<Duke> { }
public class Earl : RoyalBase<Earl> { }
public class Baron : RoyalBase<Baron> { }
  1. 每个King都有一张其他King的列表,他们是国王的敌人。
  2. King有n Prince个孩子和
  3. 每个Prince都有n Duke个孩子
  4. 每个Duke都有n Earl个孩子
  5. 每个Earl都有n Baron个孩子
  6. 因此,我们有四个下降的父/子关系。每个文档使用的id是文档上的Name属性。

    使用这种设置的强类型内部命中搜索的示例将是

    var response = client.Search<Duke>(s => s
        .Index(index)
        .InnerHits(ih => ih
            .Type<Earl>("earls", g => g
                .Size(5)
                .InnerHits(iih => iih
                    .Type<Baron>("barons")
                )
                .FielddataFields(p => p.Name)
            )
        )
    );
    

    然后处理响应,演示了强类型访问的几种方法

    foreach (var hit in response.Hits)
    {
        // each hit here is a Hit<ILazyDocument> i.e.
        // no strongly typed access
        var earlHits = hit.InnerHits["earls"].Hits;
    
        // strongly typed access to documents using
        // .Documents<T>()
        var earls = earlHits.Documents<Earl>();
    
        foreach (var earlHit in earlHits.Hits)
        {
            // use Source.As<T> to access source strongly typed
            var earl = earlHit.Source.As<Earl>().Name;
    
            var baronHits = earlHit.InnerHits["barons"];
    
            // strongly typed access to documents
            var baron = baronHits.Documents<Baron>();
    
            // do something with baron documents
        }
    }
    

    访问响应时需要知道类型,因为客户端不存储或保持内部命中的名称与C#类型的关系。

    内部匹配在内部反序列化为Json.Net JObject类型,.Source.As<T>().Documents<T>()在Json.Net中使用JToken.ToObject<T>()来执行转换。