2

I have an array of objects inside a document in ES

I want to only match documents where 2 fields inside an object (within the array) match.

My problem is this. Say I have 3 documents (outer document removed) where I have an array of objects such as

                       // 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"
                        }
                    ]

And my query is

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

}

I'm currently getting matches for documents 1 and 3. Whereas I only want the first document to match where question = First yes no question and answer = Yes

How can this be achieved?

1 Answer 1

2

You need to define questionAnswers field to be of nested type so that each array object in it can be queried separately, and you can use inner_hits to get only matching document in the result.

Adding a working example with index mapping, search query and search result

Index Mapping:

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

Search Query:

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

Search Result:

"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"
                  }
                }
              ]
            }
          }
        }
      }
    ]
Sign up to request clarification or add additional context in comments.

2 Comments

@David Billings please go through the answer, and let me know if this resolved your issue ?
Thank you for your help, yes this works as I need it to!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.