我正在使用NEST 2客户端对我们的Elasticsearch执行查询。
我们有一个查询来查询嵌套文档数组,并使用.InnerHits()在结果中包含嵌套文档的匹配项。
有没有办法强制将InnerHits的结果输入到特定的POCO类而不是动态访问结果字段?
答案 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> { }
King
都有一张其他King
的列表,他们是国王的敌人。 King
有n Prince
个孩子和Prince
都有n Duke
个孩子Duke
都有n Earl
个孩子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)
)
)
);
然后处理响应,演示了强类型访问的几种方法
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>()
来执行转换。