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

Mon*_*ire 2 elasticsearch nest

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

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

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

Rus*_*Cam 5

就在这里; 这是内部命中集成测试的一个例子 ; 对于任何可以返回内部命中的搜索,原则都是相同的

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> { }
Run Code Online (Sandbox Code Playgroud)
  1. 每个人King都有一张其他King人的名单,他们是国王的敌人.
  2. A King有n个Prince孩子和
  3. 每个人Prince都有n个Duke孩子
  4. 每个人Duke都有n个Earl孩子
  5. 每个人Earl都有n个Baron孩子

因此,我们有四个下降的父/子关系.用于每个文档的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)
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

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

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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