Elasticsearch: check exist a key in the field of type object

Viewed 718

My index test has the next mapping:

{
  "test" : {
    "mappings" : {
      "_doc" : {
        "properties" : {
          "bar" : {
            "type" : "keyword"
          },
          "baz" : {
            "type" : "long"
          },
          "foo" : {
            "type" : "object",
            "enabled" : false
          }
        }
      }
    }
  }
}

The index has 2 documents:

{
  "total": 2,
  "max_score": 1.0,
  "hits": [
    {
      "_index": "test",
      "_type": "_doc",
      "_id": "1",
      "_score": 1.0,
      "_source": {
        "baz": 123,
        "bar": [
          "php",
          "python"
        ],
        "foo": {
          "1": "bla",
          "2": "blu"
        }
      }
    },
    {
      "_index": "test",
      "_type": "_doc",
      "_id": "2",
      "_score": 1.0,
      "_source": {
        "baz": 123,
        "bar": [
          "java",
          "python"
        ],
        "foo": {
          "3": "blue",
          "4": "blae"
        }
      }
    }
  ]
}

I want to get only the docs that contain key 1 in the field foo. (So in my case this is a document where _id = 1).

Which query is suitable for this?

Elasticsearch version 6.5

1 Answers

You've set "enabled": false in your mapping. Set it to true or rather remove it which would again set it to true by default.

The purpose of enabled if it is set to true is that it would allow ES to create an inverted index for the fields so that they would be searchable. Making it false would mean that ES would simply skip reading those fields and its contents entirely.

Note that by default if you do not specify it in your mapping, it is set to true.

Below is how your mapping would be:

PUT <your_index_name>
{
    "mappings" : {
        "properties" : {
          "bar" : {
            "type" : "keyword"
          },
          "baz" : {
            "type" : "long"
          },
          "foo" : {
            "type" : "object",
            "enabled" : true       <---- Note this, either this or remove this to have this option
          }

      }
    }
}

Once you do that, you can just make use of exists query to get what you want.

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field": "foo.1"
          }
        }
      ]
    }
  }
}

Suggested Solution:

From what I understand based on the comments, you have ids of documents as sub-fields inside your object type.

Why not change your mapping to something like below:

POST my_sample_index
{
   "mappings":{
      "properties":{
         "bar":{
            "type":"keyword"
         },
         "baz":{
            "type":"long"
         },
         "foo":{
            "type":"object",
            "properties":{
               "id":{                       <--- Field for id
                  "type":"keyword"
               },
               "value":{                    <--- Corresponding field for its value
                  "type":"text"
               }
            }
         }
      }
   }
}

That way the document would be as below:

POST my_sample_index/_doc/1
{
   "baz":123,
   "bar":[
      "java",
      "python"
   ],
   "foo":[
      {
         "id":"1",
         "value":"blue"
      },
      {
         "id":2,
         "value":"black"
      }
   ]
}

Now you can simply query based on the value of id field with as simple as Term Query:

POST my_exists_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "foo.id": "1"
          }
        }
      ]
    }
  }
}

Now you can see that number of fields in your mapping would only be two id and value instead of having it created dynamically esp when the number of documents you'd possibly have would be non-deterministic.

Important Note: You may also want to check nested datatype instead of object. Also if you are using nested datatype, you have to make use of Nested Queries. Please do read the aforementioned links as why I'm suggesting you to go through them.

Hope it helps!

Related