#elasticsearch #elasticsearch-5
#elasticsearch #elasticsearch-5
Вопрос:
Я хочу создать запрос на версии 5.6, где я нахожу все книги, которые:
- принадлежат пользователю или помечены этим пользователем как избранные
- а затем отсортируйте их по тому факту, что они являются его любимыми первыми и последующими по дате. Запись в книге будет выглядеть следующим образом
{
title: "book1"
users_favourite: ["1", "2"],
userid: "1",
date: timestamp
}
У меня есть большая часть запросов, но я не знаю, как поместить любимые книги сверху и отсортировать по дате:
{
"from" : 0,
"size" : 51,
"query" : {
"bool" : {
"should" : [
{
"match" : {
"users_favourite" : {
"query" : "1",
"operator" : "OR"
}
}
},
{
"term" : {
"userid" : {
"value" : "1"
}
}
}
]
}
},
"sort" : [
{
"date" : {
"order" : "desc",
"missing" : "_last",
"unmapped_type" : "string"
}
}
]
}
Таким образом, результат будет следующим: сначала все любимые книги пользователей, отсортированные по дате
, за которыми следуют книги, принадлежащие этому пользователю, также упорядоченные по дате.
избранное пользователя | Дата |
---|---|
верно | 2021 |
верно | 2020 |
верно | 2018 |
ложь | 2021 |
ложь | 2019 |
ложь | 2017 |
Комментарии:
1. 1. Каков тип сопоставления для «users_favourite «? 2. Может ли запрос искать несколько «users_favourite» или только один? 3. Может ли «users_favourite» быть пустым?
2. 1. сопоставление users_favourite является ключевым словом 2. Я всегда запрашиваю одного пользователя 3. да, users_favourite cab должен быть пустым
Ответ №1:
Общее решение, которое я бы использовал, выглядит примерно так
Что касается сортировки:
GET social_unique_flat_verified_guesses/_search
{
"from": 0,
"size": 51,
"query": {
"bool": {
"should": [
{
"match": {
"users_favourite": {
"query": "1",
"operator": "OR"
}
}
},
{
"term": {
"userid": {
"value": "1"
}
}
}
]
}
},
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "doc['users_favourite'].contains(params.users_favourite) ? 1 : 0",
"params": {
"users_favourite": "1"
}
},
"order": "desc"
}
},
{
"date": {
"order": "desc",
"missing": "_last",
"unmapped_type": "string"
}
}
]
}
Это указывает elastic сначала оценить все совпадающие (1 или 0), если книга находится в избранном пользователем, а затем по годам.
Кроме того, я бы изменил предложение should для избранного пользователя на это
"term": {
"users_favourite": {
"value": "1"
}
}
Имейте в виду, что если поле «users_favourite» может быть пустым, или если запрос может выполнять поиск по нескольким избранным пользователем, запрос должен быть немного другим. Так что дайте мне знать, и я отредактирую его
Комментарии:
1. Спасибо @ron-serruya, это решение работает. Одно из изменений, которое я должен был сделать, это удалить значение, чтобы источником был «doc[‘users_favourite’].contains(params.users_favourite) ? 1 : 0»
2. @rPawel Да, вы правы, .value принимает первый индекс вместо всего списка