Запрос 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
        }
    ]
}

По сути, объект может иметь несколько атрибутов (массив свойств).

Эти атрибуты могут быть разными для каждого клиента. В этом примере у меня есть 2 типа атрибутов: a и tag, однако другие документы могут иметь другие атрибуты, такие как weight, vendor, size и т. д., поэтому модель должна быть достаточно общей, чтобы поддерживать заранее неизвестные атрибуты.

Атрибут может быть списком ключевых слов (например, power) или числовым значением (например, tags).

Мне нужен запрос ES для получения документов weight с помощью этого псевдозапроса:

ids

Мне удалось получить этот запрос, который, кажется, работает так, как ожидалось:

{
    "_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. Это правильный запрос или я случайно получаю правильные результаты?
  2. Является ли запрос (или сопоставление) оптимальным или мне следует что-то переосмыслить?
  3. Можно ли упростить запрос?
0
0
144
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Запрос правильный.
  2. Отображение отличное, а запрос оптимален.
  3. Хотя запрос можно упростить:
{
  "_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, так что... Вы можете использовать то, что у вас есть.

Другие вопросы по теме