Как сопоставить несколько полей для каждого элемента массива в эластичном поиске

Я пытаюсь создать эластичный поисковый запрос для соответствия нескольким полям внутри объекта внутри массива.

Например, структура Elastic Search, к которой я обращаюсь, похожа на следующую:

"hits": [
            {
                "_index": "titles",
                "_type": "title",
                ...
                "_source": {
                    ...
                    "genres": [
                        {
                            "code": "adventure",
                            "priority": 1
                        },
                        {
                            "code": "action",
                            "priority": 2
                        },
                        {
                            "code": "horror",
                            "priority": 3
                        }
                    ],
                    ...
                },
                ...
        ]

И то, что я пытаюсь сделать, это сопоставить названия с определенными парами жанр/приоритет. Например, я пытаюсь сопоставить все заголовки с code=action и priority=1, но мой запрос возвращает слишком много результатов. Приведенный выше заголовок попадает в этот пример из-за того, что список жанров содержит как жанр с code=action, так и другой жанр, который соответствует priority=1. Мой запрос похож на следующий:

    "query": {
        "bool": {
            "filter": [
                {
                    "bool": {
                        "must":[
                            {"term": {
                                    "genres.code": {
                                        "value": "action",
                                        "boost": 1.0
                                    }
                            }},
                            {"term": {
                                    "genres.priority": {
                                        "value": 1,
                                        "boost": 1.0
                                    }
                            }}
                        ]
                    }                    
                },
                ...
            }

Есть ли способ сформировать запрос, чтобы сопоставить заголовок с одним жанром, содержащим как priority=1, так и code=action?

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
3
0
2 739
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я воссоздал вашу проблему. Я добавил следующее сопоставление

PUT titles 
{
  "mappings": {
    "title": {
      "properties": {
        "author": {
          "type": "text"
        },
        "genres": {
          "type": "nested"
        }
      }
    }
  }
}

Затем я добавил значения в index. Это то, что было вставлено

  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_index": "titles",
        "_type": "title",
        "_id": "2",
        "_score": 1,
        "_source": {
          "author": "Author 1",
          "genres": [
            {
              "code": "adventure",
              "priority": 2
            },
            {
              "code": "action",
              "priority": 3
            },
            {
              "code": "horror",
              "priority": 1
            }
          ]
        }
      },
      {
        "_index": "titles",
        "_type": "title",
        "_id": "1",
        "_score": 1,
        "_source": {
          "author": "Author 2",
          "genres": [
            {
              "code": "adventure",
              "priority": 3
            },
            {
              "code": "action",
              "priority": 1
            },
            {
              "code": "horror",
              "priority": 2
            }
          ]
        }
      },
      {
        "_index": "titles",
        "_type": "title",
        "_id": "3",
        "_score": 1,
        "_source": {
          "author": "Author 3",
          "genres": [
            {
              "code": "adventure",
              "priority": 3
            },
            {
              "code": "action",
              "priority": 1
            },
            {
              "code": "horror",
              "priority": 2
            }
          ]
        }
      }
    ]
  }

Мой запрос:

GET titles/title/_search 
{
  "query": {
    "nested": {
      "path": "genres",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "genres.code": {
                  "value": "horror"
                }
              }
            },
            {
              "term": {
                "genres.priority": {
                  "value": 1
                }
              }
            }
          ]
        }
      }
    }
  }
}

Запрос возвращает

        "_source": {
          "author": "Author 1",
          "genres": [
            {
              "code": "adventure",
              "priority": 2
            },
            {
              "code": "action",
              "priority": 3
            },
            {
              "code": "horror",
              "priority": 1
            }
          ]
        }

Это название — единственное, имеющее код = «ужас» и приоритет = 1.

Это правильное решение. Ключевое слово, которое я искал как для отображения, так и для поиска, было nested.

Brad 22.05.2019 20:47

Я искал это nested решение какое-то время и так и не нашел его. Большое спасибо Леандро, чтобы помочь мне с этим!

Guilherme Lages Santos 12.03.2021 16:08

Отличный уровень детализации. Спасибо.

Fishcake 17.09.2021 10:28

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