Сопоставление документов, в которых несколько полей совпадают в массиве объектов

#elasticsearch

Вопрос:

У меня есть массив объектов внутри документа в ES

Я хочу сопоставлять только документы, в которых совпадают 2 поля внутри объекта (в массиве).

Моя проблема в следующем. Допустим, у меня есть 3 документа (внешний документ удален), в которых у меня есть массив объектов, таких как

                        // Doc 1
                        "questionAnswers": [
               
                        {
                            "question": "First yes no question",
                            "answer": "Yes"
                        },
                        {
                            "question": "Second yes no question",
                            "answer": "No"
                        }
                    ]


                       // Doc 2
                        "questionAnswers": [
               
                        {
                            "question": "First yes no question",
                            "answer": "No"
                        },
                        {
                            "question": "Second yes no question",
                            "answer": "No"
                        }
                    ]


                       // Doc 3
                        "questionAnswers": [
               
                        {
                            "question": "First yes no question",
                            "answer": "No"
                        },
                        {
                            "question": "Second yes no question",
                            "answer": "Yes"
                        }
                    ]
 

И мой вопрос таков

 {
"from": 0,
"size": 25,
"query": {
    "bool": {
        "filter": [
            {
                "match": {
                    "questionAnswers.question.keyword": "First yes no question"
                }
            },
            {
                    "match": {
                        "questionAnswers.answer": "Yes"
                    }
                
            }
        ]
    }
}
 

}

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

Как этого можно достичь?

Ответ №1:

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

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

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

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

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

 {
  "query": {
    "nested": {
      "path": "questionAnswers",
      "query": {
        "bool": {
          "filter": [
            {
              "match": {
                "questionAnswers.question.keyword": "First yes no question"
              }
            },
            {
              "match": {
                "questionAnswers.answer": "Yes"
              }
            }
          ]
        }
      },
      "score_mode": "avg",
      "inner_hits": {}
    }
  }
}
 

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

 "hits": [
      {
        "_index": "68760699",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "questionAnswers": [
            {
              "question": "First yes no question",
              "answer": "Yes"
            },
            {
              "question": "Second yes no question",
              "answer": "No"
            }
          ]
        },
        "inner_hits": {
          "questionAnswers": {
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": 0.0,
              "hits": [
                {
                  "_index": "68760699",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "questionAnswers",
                    "offset": 0
                  },
                  "_score": 0.0,
                  "_source": {
                    "question": "First yes no question",           //note this
                    "answer": "Yes"
                  }
                }
              ]
            }
          }
        }
      }
    ]
 

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

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

2. Спасибо вам за вашу помощь, да, это работает так, как мне нужно!