#elasticsearch
Вопрос:
В Elasticsearch предположим, что я создал users
индекс. Этот индекс имеет внутреннее поле как вложенное, поэтому я могу рассматривать его как массив.
Пример вставленных данных:
[{
“isActive”: true,
“id”: “0183284A-92BE-4CD7-8C76-98225562B4CB”,
“actions”: [{
“createdDate”: 1623895434,
“userId”: “2B042D11-FD7E-4919-832A-ADBA3C63160C”,
“type”: 0
},
{
“createdDate”: 1623896475,
“userId”: “4E3B2ACF-8D21-4CA8-865A-5A128873A6D9”,
“type”: 0
}
]
},
{
“isActive”: true,
“id”: “2B042D11-FD7E-4919-832A-ADBA3C63160C”,
“actions”: [{
“createdDate”: 1623805703,
“userId”: “0183284A-92BE-4CD7-8C76-98225562B4CB”,
“type”: 0
},
{
“createdDate”: 1623895929,
“userId”: “4E3B2ACF-8D21-4CA8-865A-5A128873A6D9”,
“type”: 0
}
]
},
{
“isActive”: true,
“id”: “4E3B2ACF-8D21-4CA8-865A-5A128873A6D9”,
“actions”: [{
“createdDate”: 1623893475,
“userId”: “0183284A-92BE-4CD7-8C76-98225562B4CB”,
“type”: 0
}]
}
]
Итак, теперь скажите, что я вставил вышеуказанные 3 объекта в users
индекс и сопоставил actions
поле как вложенное.
Мне нужно иметь возможность выполнить запрос для извлечения всех пользователей, которые предприняли действия против другого пользователя:
GET users/_search?pretty
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "actions",
"query": {
"bool": {
"must": [
{ "match": { "actions.userId.keyword": "4E3B2ACF-8D21-4CA8-865A-5A128873A6D9" }
}
]
}
},
"inner_hits": { }
}
}
]
}
},
"_source": false
}
Таким образом, это вернет всех пользователей, у которых есть действия, включающие идентификатор пользователя = 4E3B2ACF-8D21-4CA8-865A-5A128873A6D9
:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.6931471,
"hits": [{
"_index": "users",
"_type": "_doc",
"_id": "0183284A-92BE-4CD7-8C76-98225562B4CB",
"_score": 0.6931471,
"inner_hits": {
"actions": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931471,
"hits": [{
"_index": "users",
"_type": "_doc",
"_id": "0183284A-92BE-4CD7-8C76-98225562B4CB",
"_nested": {
"field": "actions",
"offset": 0
},
"_score": 0.6931471,
"_source": {
"createdDate": 1623896475,
"userId": "4E3B2ACF-8D21-4CA8-865A-5A128873A6D9",
"type": 0
}
}]
}
}
}
},
{
"_index": "users",
"_type": "_doc",
"_id": "2B042D11-FD7E-4919-832A-ADBA3C63160C",
"_score": 0.6931471,
"inner_hits": {
"actions": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931471,
"hits": [{
"_index": "users",
"_type": "_doc",
"_id": "2B042D11-FD7E-4919-832A-ADBA3C63160C",
"_nested": {
"field": "actions",
"offset": 0
},
"_score": 0.6931471,
"_source": {
"createdDate": 1623895929,
"userId": "4E3B2ACF-8D21-4CA8-865A-5A128873A6D9",
"type": 0
}
}]
}
}
}
}
]
}
}
Теперь я хочу отсортировать всех извлеченных пользователей на основе actions.createdDate
. Как сделать подобное, пожалуйста?
Ответ №1:
script_score
Подойдет ли вам здесь запрос? Мы бы по-прежнему требовали, чтобы запрос соответствовал вашему текущему идентификатору пользователя, но затем оценивали результаты на основе createdDate
значения в части сценария.
GET users/_search?pretty
{
"query": {
"nested": {
"path": "actions",
"query": {
"script_score": {
"query": {
"match": { "actions.userId.keyword": "4E3B2ACF-8D21-4CA8-865A-5A128873A6D9" }
},
"script": {
"source": "doc['actions.createdDate'].value"
}
}
}
}
},
"_source": false
}
Если это сработает , результаты будут отсортированы по убыванию createdDate
, вы можете использовать обратную сортировку по возрастанию.