1

So, I have a metadata data field in my index which is in the following format.

metadata: [
 {
    "key": "type",
    "value": "animal"
 },
 {
    "key": "animal",
    "value": "cat"
 }
]

The array can have thousands of objects, and I cannot change the structure of this field.
My client application requests the server with key=value format. How do I write elastic search query to get the result?

Request query type=animal should return only 1st object from the array (not 2nd).
Request query animal=cat should return only 2nd object from the array (not 1st).
Request query type=cat should not return anything.

How can it be achieved? I am worn out trying to figure out the correct query.

1 Answer 1

1

According to your question, you have to return only the matching object from the array based on the query.

On the basis of Elasticsearch Array docs

Arrays of objects do not work as you would expect: you cannot query each object independently of the other objects in the array. If you need to be able to do this then you should use the nested datatype instead of the object datatype.

If you want to query on each object of the array and return only the specific object from the array, you need to use a nested query with inner_hits. But for using the nested query, you have to create a new index with nested mapping

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

Index Mapping:

PUT <index-name>
{
  "mappings": {
    "properties": {
      "metadata":{
        "type":"nested"
      }
    }
  }
}

Index Data:

POST <index-name>/_doc/1
{
  "metadata": [
    {
      "key": "type",
      "value": "animal"
    },
    {
      "key": "animal",
      "value": "cat"
    }
  ]
}

Search Query:

POST <index-name>/_search
{
  "query": {
    "nested": {
      "path": "metadata",
      "query": {
        "match": {
          "metadata.key": "animal"
        }
      },
      "inner_hits": {}
    }
  }
}

Search Result:

"inner_hits" : {
          "metadata" : {
            "hits" : {
              "total" : {
                "value" : 1,
                "relation" : "eq"
              },
              "max_score" : 0.6931471,
              "hits" : [
                {
                  "_index" : "70711376",
                  "_type" : "_doc",
                  "_id" : "1",
                  "_nested" : {
                    "field" : "metadata",
                    "offset" : 1
                  },
                  "_score" : 0.6931471,
                  "_source" : {
                    "value" : "cat",
                    "key" : "animal"
                  }
                }
              ]
            }
          }
        }
Sign up to request clarification or add additional context in comments.

1 Comment

@paradox its been a long time ! Can you please accept and upvote the answer, if it helped you resolve your issue. TIA ;-)

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.