Элемент сортировки по массивам не работает в Elasticsearch при загрузке Spring с использованием API Java
У меня проблема (или нехватка знаний) при сортировке документов в asticsearch. Elasticsearch является локальным и управляется весенней загрузкой. То, что я пытаюсь сделать, это, используя Java API, искать документы и сортировать их. Документы выглядят примерно так (немного упрощенно):
{
(...)
"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
2 ответа
Хорошо
проблема была не в структуре запроса или документа, а в значении поля...
он был разделен дефисом, поэтому упругий поиск не содержал его как целую строку, а как отдельные токены. Решение состоит в том, чтобы установить это поле (или добавить подполе) с помощью свойства not_analyzed с индексом... В Java это можно было бы сделать, добавив аннотацию к полю, как это или подобное:
@Field(
type = FieldType.String,
index = FieldIndex.not_analyzed
)
relationSet seems like a nested field in your schema.
Для сортировки по вложенным полям следует обратиться по ссылке ниже
Ссылка: 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
}
}],
ОБНОВИТЬ:
Вы должны явно отметить 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: удалить индекс и воссоздать, прежде чем продолжить