Elasticsearch嵌套排序

我正在尝试在Elasticsearch中进行嵌套排序,但到目前为止还没有成功。

我的数据结构:

{ "_id" : 1, "authorList" : [ {"lastName":"hawking", "firstName":"stephan"}, {"lastName":"frey", "firstName":"richard"} ] } { "_id" : 2, "authorList" : [ {"lastName":"roger", "firstName":"christina"}, {"lastName":"freud", "firstName":"damian"} ] } 

我想根据文件中第一作者的姓氏对文件进行排序。

使用的映射:

 "authorList" : { "type" : "nested", "properties" : {"lastName":{"type":"keyword"}}} 

使用SearchRequestBuilder(JAVA)排序:

  searchRequestBuilder.addSort( SortBuilders.fieldSort("authorList.lastName") .order(SortOrder.ASC) .sortMode(SortMode.MIN) .setNestedPath("authorList") ) 

这可行,但不会给出想要的结果(例如,首先“叫卖”然后“罗杰”)。

我错过了什么吗? 有没有办法表明Elasticsearch访问数组authorList的index = 0? 是否有任何映射/规范化器分别索引数组的第一个条目?

嵌套文档不会保存为简单数组或列表。 它们由Elasticsearch内部管理:

Elasticsearch仍然基本平坦,但它在内部管理嵌套关系,以提供嵌套层次结构的外观。 当您创建嵌套文档时,Elasticsearch实际上会索引两个单独的文档(根对象和嵌套对象),然后在内部将它们关联起来。 (更多这里 )

我认为你需要向elasticsearch提供一些额外的信息,这些信息将成为作者“主要/第一”的指标。 仅将此附加字段放在嵌套对象中的一个作者(您的映射可以像以前一样保留)就足够了,如下所示:

 { "authorList" : [ {"lastName":"roger", "firstName":"christina", "authorOrder": 1}, {"lastName":"freud", "firstName":"damian"} ] }, { "authorList" : [ {"lastName":"hawking", "firstName":"stephan", "authorOrder": 1}, {"lastName":"adams", "firstName": "mark" } {"lastName":"frey", "firstName":"richard"} ] }, { "authorList" : [ {"lastName":"adams", "firstName":"monica", "authorOrder": 1}, {"lastName":"adams", "firstName":"richard"} ] } 

那么查询可以是:

 { "query" : { "nested" : { "query" : { "bool" : { "must" : [ { "match" : { "authorList.authorOrder" : 1 } } ] } }, "path" : "authorList" } }, "sort" : [ { "authorList.lastName" : { "order" : "asc", "nested_filter" : { "bool" : { "must" : [ { "match" : { "authorList.authorOrder" : 1 } } ] } }, "nested_path" : "authorList" } } ] } 

并使用Java API:

 QueryBuilder matchFirst = QueryBuilders.boolQuery() .must(QueryBuilders.matchQuery("authorList.authorOrder", 1)); QueryBuilder mainQuery = QueryBuilders.nestedQuery("authorList", matchFirst, ScoreMode.None); SortBuilder sb = SortBuilders.fieldSort("authorList.lastName") .order(SortOrder.ASC) .setNestedPath("authorList") .setNestedFilter(matchFirst); SearchRequestBuilder builder = client.prepareSearch("test") .setSize(50) .setQuery(mainQuery) .addSort(sb); 

请注意, SortBuilder具有.setNestedFilter(matchAll) ,这意味着排序基于authorList.lastName字段,但仅基于“主要/第一”嵌套元素 。 没有它,elasticsearch将首先对所有嵌套文档进行排序,从升序排序列表中选择第一个元素,并在此基础上对父文档进行排序。 所以带有“霍金”的文件可能是第一个,因为它有“亚当斯”的姓氏。

最终结果是:

 "authorList" : [ {"lastName":"adams", "firstName":"monica", "authorOrder": 1}, {"lastName":"adams", "firstName":"richard"} ], } "authorList" : [ {"lastName":"hawking", "firstName":"stephan", "authorOrder": 1}, {"lastName":"adams", "firstName":"mark"}, {"lastName":"frey", "firstName":"richard"} ] }, { "authorList" : [ {"lastName":"roger", "firstName":"christina", "authorOrder": 1}, {"lastName":"freud", "firstName":"damian"} ] }