#elasticsearch
#elasticsearch
Вопрос:
У меня есть два документа в эластичном поиске со следующими значениями
uid preferences
1 [10,20,30,40,50,60,70,80,100]
2 [20,70,30,100,1000,77,45]
Есть ли какой-либо способ, которым мы можем выполнить пересечение массива по предпочтениям для этих двух записей и получить результат [20,70,30,100]
? В настоящее время мы отправляем эти две записи на сервер приложений и выполняем intersect , но хотели проверить, есть ли какой-либо прямой способ получения значений intersect напрямую из Elasticsearch.Спасибо.
Комментарии:
1. Пересекать значения для чего? Для группы идентификаторов документов? Или просто пара из 2, как в вашем примере?
2. Спасибо @JoeSorocin за ваш комментарий . Пара из 2, как указано в примере, в порядке.
Ответ №1:
Я бы решил это с помощью параметризованной скриптовой агрегации метрик. Вот более читаемая версия:
{
"size": 0,
"query": {
"terms": {
"id": [
1,
2
]
}
},
"aggs": {
"preferences_intersection": {
"scripted_metric": {
"init_script": "state.shared_vals = [];",
"map_script": "state.shared_vals.addAll(new ArrayList(doc['preferences']));",
"combine_script": """
return state.shared_vals.stream()
.filter(i -> Collections.frequency(state.shared_vals, i) >= params.compared_docs_count)
.sorted((o1, o2) -> o1.compareTo(o2))
.collect(Collectors.toCollection(TreeSet::new))
""",
"reduce_script": "return states[0]",
"params": {
"compared_docs_count": 2
}
}
}
}
}
Обратите внимание, как terms
был применен запрос, params.compared_docs_count
чтобы мы могли проверить количество вхождений общих значений.
Вот компактная версия запроса без тройных кавычек:
{"size":0,"query":{"terms":{"id":[1,2]}},"aggs":{"preferences_intersection":{"scripted_metric":{"init_script":"state.shared_vals = [];","map_script":"state.shared_vals.addAll(new ArrayList(doc['preferences']));","combine_script":" return state.shared_vals.stream()n .filter(i -> Collections.frequency(state.shared_vals, i) >= params.compared_docs_count)n .sorted((o1, o2) -> o1.compareTo(o2))n .collect(Collectors.toCollection(TreeSet::new))","reduce_script":"return states[0]","params":{"compared_docs_count":2}}}}}
Комментарии:
1. Спасибо @JoeSorocin за ваш ответ. Поскольку это основанное на сценарии мышление о проблемах с производительностью. Удачи вашему «Руководству по Elasticsearch»
2. Спасибо! Да, сценарии, как правило, работают медленно, но в этом мы просматриваем только 2 документа благодаря
terms
запросу, поэтому я бы не стал беспокоиться об этом.