#elasticsearch
#elasticsearch
Вопрос:
У меня есть это сопоставление в ES 7.9:
{
"mappings": {
"properties": {
"cid": {
"type": "keyword",
"store": true
},
"id": {
"type": "keyword",
"store": true
},
"a": {
"type": "nested",
"properties": {
"attribute":{
"type": "keyword"
},
"key": {
"type": "keyword"
},
"num": {
"type": "float"
}
}
}
}
}
}
И некоторые документы, проиндексированные как:
{
"cid": "177",
"id": "1",
"a": [
{
"attribute": "tags",
"key": [
"heel",
"thong",
"low_heel",
"economic"
]
},
{
"attribute": "weight",
"num": 15
}
]
}
В принципе, объект может иметь несколько атрибутов ( a
массив свойств).
Эти атрибуты могут отличаться для каждого клиента. В этом примере у меня есть 2 типа атрибутов: tag
и weight
, однако другие документы могут иметь другие атрибуты, такие как vendor
, size
, power
, и т.д., Поэтому модель должна быть достаточно общей, чтобы поддерживать заранее неизвестные атрибуты.
Атрибут может быть списком ключевых слов (например tags
) или числовым значением (например weight
).
Мне нужен запрос ES для извлечения документов ids
с помощью этого псевдозапроса:
cid="177" and (tag="flat" or tag="heel") and tag="economic" and weight<20
Мне удалось выполнить этот запрос, который, похоже, работает должным образом:
{
"_source": ["id"],
"query": {
"bool": {
"must" : [
{"term" : { "cid" : "177" }},
{
"nested": {
"path": "a",
"query": {
"bool":{
"must":[
{"term" : { "a.attribute": "tags"}},
{"terms" : { "a.key": ["flat","heel"]}}
]
}
}
}
},
{
"nested": {
"path": "a",
"query": {
"bool":{
"must":[
{"term" : { "a.attribute": "tags"}},
{"term" : { "a.key": "economic"}}
]
}
}
}
},
{
"nested": {
"path": "a",
"query": {
"bool":{
"must":[
{"term" : { "a.attribute": "weight" } },
{"range": { "a.num": {"lt": 20} } }
]
}
}
}
}
]
}
}
}
- Правильный ли этот запрос или я случайно получаю правильные результаты?
- Является ли запрос (или сопоставление) оптимальным или я должен что-то переосмыслить?
- Можно ли упростить запрос?
Ответ №1:
- Запрос правильный.
- Сопоставление отличное, а запрос оптимальный.
- Хотя запрос можно упростить:
{
"_source": [
"id"
],
"query": {
"bool": {
"must": [
{
"term": {
"cid": "177"
}
},
{
"nested": {
"path": "a",
"query": {
"query_string": {
"query": "a.attribute:tags AND ((a.key:flat OR a.key:heel) AND a.key:economic)"
}
}
}
},
{
"nested": {
"path": "a",
"query": {
"query_string": {
"query": "a.attribute:weight AND a.num:<20"
}
}
}
}
]
}
}
}
это было бы менее оптимально из-за того, что их query_strings
все равно нужно было бы внутренне скомпилировать, по сути, в DSL запроса, который у вас есть выше. Кроме того, вам все равно понадобятся две отдельные nested
группы so… Вы можете использовать то, что у вас есть.