使用 java API 在 Spring 引导时,对数组元素排序在 Elasticsearch 中不起作用

Sort on arrays element don't work in Elasticsearch on Spring boot using java API

我在 elasticsearch 中排序文档时遇到问题(或缺乏知识)。 Elasticsearch 是本地的,由 spring boot 管理。我想做的是使用 java API 搜索文档并对其进行排序。 Te docs 看起来像那样(稍微简化):

{
(...)
"relatedDocuments": [{
    "_id": ObjectId("123123"),
    (...)
    "relationSet": [{
        "type": {
            "name": "Some name",
            "version": NumberLong(1)
        },
        "documentId": "123123",
        "content": {
            "numberToSearch": "U-2016-8"<---element to sort by
        }
    }]
    (...)
}]
(...)
}

如您所见,要排序的元素在对象中,该对象在数组中,而对象在另一个数组中的其他对象中...

现在我正在做一些似乎工作正常但排序的查询......就像从未发生过排序......Java 代码看起来像:

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //some bool query created
        boolQuery.must(query);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withSort(SortBuilders.fieldSort("relatedDocuments.relationSet.content.numberToSearch").order(SortOrder.ASC).sortMode("min")).withQuery(boolQuery).build();

        return elasticsearchTemplate.queryForList(searchQuery, GenericDocumentIndex.class);

结果被正确搜索但根本没有排序...

如果我将 fieldSort 更改为像 "relatedDocuments.id" 这样更简单的东西,那么排序工作...

这里有什么问题?

编辑
作为参考,结果记录排序如下:

U-2016-5
U-2016-6
U-2016-7
U-2016-4
U-2016-8
U-2016-9
U-2016-12
U-2016-11
U-2016-10

relationSet seems like a nested field in your schema. 

关于嵌套字段的排序,您应该参考下面的link

参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-sorting.html

"sort": [{
        "relatedDocuments.relationSet.content.numberToSearch": {
            "nested_path": "relatedDocuments.relationSet",
            "mode": "min",
            "order": "desc",
            "ignore_unmapped": false
        }
    }],

更新:

您需要通过 spring-boot

relationSet 明确标记为嵌套
@Document(indexName = "indexName", type = "inxedType", shards = 1, replicas = 0)
public class RelatedDocuments {
@Field(type= FieldType.Nested)  // <-- mark it as nested
private List<Relation> relationSet;   
}

PS : 删除索引并在继续之前重新创建

好的
问题不在查询或文档结构中,而是在字段值中...

它是破折号分隔的,所以弹性搜索没有将它作为整个字符串保存,而是作为分隔的标记保存。 解决方案是使用索引 not_analyzed 属性设置此字段(或添加子字段)... 在 java 中,可以通过像这样或类似的方式在字段上添加注释来完成:

@Field(
        type = FieldType.String,
        index = FieldIndex.not_analyzed
)