Как применить комбинацию фильтров к массиву объектов в elasticsearch?

#elasticsearch

Вопрос:

Привет, пожалуйста, помогите мне написать подходящий запрос для моей задачи, у меня есть список продуктов с разными категориями и связанными атрибутами и тегами. Вот два документа для двух категорий вместе со связанным списком атрибутов. Может быть несколько атрибутов, просто отображающих один.

    {
   "category": "blouses",
   "attributes": [
       {
           "attribute": "women-blouse-neckline",
           "tag": "round-neck"
       }
   ]
}

{
   "category": "dresses",
   "attributes": [
       {
           "attribute": "women-dress-neckline",
           "tag": "v-neck"
       }
   ]
}
 

Теперь я хочу получить список продуктов из обеих категорий, которые являются dresses и blouses , но вместе с тем конкретный случай на уровне атрибутов :
Извлеките все продукты, из dresses которых есть атрибут women-dress-neckline и тег v-neck , вместе со всеми продуктами, из blouses которых есть атрибут women-blouse-neckline и тег round-neck .
Спасибо.

Ответ №1:

Для запроса по каждому ключу "attributes" вам нужно определить «атрибуты» как вложенный тип, а затем использовать комбинацию bool/must и вложенный запрос

Добавление рабочего примера с отображением индекса, поисковым запросом и результатом поиска

Сопоставление индексов:

 {
  "mappings": {
    "properties": {
      "attributes": {
        "type": "nested"
      }
    }
  }
}
 

Поисковый запрос:

 {
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "category": "dresses"
          }
        },
        {
          "nested": {
            "path": "attributes",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "attributes.attribute.keyword": "women-dress-neckline"
                    }
                  },
                  {
                    "term": {
                      "attributes.tag.keyword": "v-neck"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
 

Результат поиска:

 "hits": [
      {
        "_index": "69611494",
        "_type": "_doc",
        "_id": "2",
        "_score": 2.0794413,
        "_source": {
          "category": "dresses",
          "attributes": [
            {
              "attribute": "women-dress-neckline",
              "tag": "v-neck"
            }
          ]
        }
      }
    ]
 

Обновление 1:

Вы можете объединить два вложенных запроса, как показано ниже

 {
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "match": {
                  "category": "dresses"
                }
              },
              {
                "nested": {
                  "path": "attributes",
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "term": {
                            "attributes.attribute.keyword": "women-dress-neckline"
                          }
                        },
                        {
                          "term": {
                            "attributes.tag.keyword": "v-neck"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "match": {
                  "category": "blouses"
                }
              },
              {
                "nested": {
                  "path": "attributes",
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "term": {
                            "attributes.attribute.keyword": "women-blouse-neckline"
                          }
                        },
                        {
                          "term": {
                            "attributes.tag.keyword": "round-neck"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
 

Комментарии:

1. @Naresh Sharma пожалуйста, ознакомьтесь с ответом и дайте мне знать, решит ли это вашу проблему?

2. Спасибо @escoder, это работает частично в соответствии с требованием. Это хорошо работает для фильтрации данных по одной категории, но не для обеих. Например: A = («атрибут»: «женское платье-вырез» и «тег»: «v-образный вырез») B = ( «атрибут»: «женщины-блузка-вырез» и «тег»: «круглый вырез») Для отдельных A или B это работает, но нам нужны данные для A B. Я попытался добавить еще один вложенный запрос и для другой категории, но он выполняет логическую операцию И и ничего не возвращает. Я также пытаюсь вставлять вложенные запросы, should но это дало мне результат, который имеет square-neck вид тега.

3. @NareshSharma вам нужны те документы, которые удовлетворяют как условию A, так и условию B.

4. Да, мне нужны данные для обоих.

5. @NareshSharma пожалуйста, просмотрите обновленный запрос и дайте мне знать, решит ли это вашу проблему?