如何使用Nest为Inner Hits结果按startsOn降序排序?
Nest Inner Hits 排序问题解决方案
问题描述
使用Nest的.Sort()方法对Inner Hits结果排序时遇到错误,文档结构如下:
{ "id": "whatever", "sales": [ { "startsOn": "2022-05-01T00:00:00", "endsOn": "2022-05-31T23:59:59", "discountPercent": 0.10 }, { "startsOn": "2022-06-01T00:00:00", "endsOn": "2022-06-30T23:59:59", "discountPercent": 0.15 } ] }
需求是将Inner Hits结果按startsOn字段降序排序,当前代码如下:
client.SearchAsync<Product>(x => x.Query(q => q.Nested(n => n.Path(p => p.sales) .Query(q => q.DateRange( /* 日期范围条件 */)) .InnerHits(ih => ih.Name("sorted_Sales")))));
添加.Sort()后触发错误:
FieldSortDescriptor 不包含“sales”的定义,也找不到可访问的扩展方法...
解决方案
错误根源是Inner Hits的排序上下文为嵌套的sales子文档,而非外层Product文档,不能直接通过外层实体的sales属性引用字段。以下是三种可行的实现方式:
方式1:直接指定嵌套字段路径字符串
通过字符串明确指定嵌套字段的完整路径:
client.SearchAsync<Product>(x => x.Query(q => q.Nested(n => n.Path(p => p.sales) .Query(q => q.DateRange( /* 日期范围条件 */)) .InnerHits(ih => ih.Name("sorted_Sales") .Sort(s => s.Descending("sales.startsOn")))));
方式2:强类型指定嵌套实体字段
如果项目中定义了sales对应的实体类(如Sales),可以通过泛型SortDescriptor<Sales>实现强类型排序:
client.SearchAsync<Product>(x => x.Query(q => q.Nested(n => n.Path(p => p.sales) .Query(q => q.DateRange( /* 日期范围条件 */)) .InnerHits(ih => ih.Name("sorted_Sales") .Sort<Sales>(s => s.Descending(sl => sl.startsOn))))));
方式3:使用Field对象引用嵌套字段
通过Field对象指向嵌套数组中的字段(索引不影响,仅用于强类型推导):
client.SearchAsync<Product>(x => x.Query(q => q.Nested(n => n.Path(p => p.sales) .Query(q => q.DateRange( /* 日期范围条件 */)) .InnerHits(ih => ih.Name("sorted_Sales") .Sort(s => s.Descending(Field<Product>(p => p.sales[0].startsOn)))))));
以上三种方式均可正确指定Inner Hits的排序规则,解决报错问题。
内容的提问来源于stack exchange,提问作者Erik Philips
相关产品推荐
相关产品推荐

