Punit Naik
Punit Naik

Reputation: 515

Elasticsearch - How to query nested fields?

I created an ES index with the command below:

curl -XPUT -H "Content-Type: application/json" http://localhost:9200/nested_test?pretty=true -d '{"mappings": {"properties": {"name": {"type": "keyword"}, "related": {"type": "nested", "properties": {"name": {"type": "keyword"}, "count": {"type": "long"}}}}}}'

Which gave me the response:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "nested_test"
}

Then I put some sample data in it:

curl -XPUT -H "Content-Type: application/json" http://localhost:9200/nested_test/_doc/1?pretty=true -d '{"name": "php", "related": [{"name": "c#", "count": 6806}, {"name": "c", "count": 4080}, {"name": "java", "count": 9745}, {"name": "javascript", "count": 9141}]}'

Which gave me the response:

{
  "_index" : "nested_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

And then I finally tried to query it using the following command:

curl -X GET http://localhost:9200/nested_test/_search?pretty=true -H 'Content-Type: application/json' -d '{"query": {"nested": {"path": "related", "query": {"match": {"related.name": "javascript"}}}}}'

And it gave me the following response:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.2039728,
    "hits" : [
      {
        "_index" : "nested_test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.2039728,
        "_source" : {
          "name" : "php",
          "related" : [
            {
              "name" : "c#",
              "count" : 6806
            },
            {
              "name" : "c",
              "count" : 4080
            },
            {
              "name" : "java",
              "count" : 9745
            },
            {
              "name" : "javascript",
              "count" : 9141
            }
          ]
        }
      }
    ]
  }
}

When I was expecting the following output:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.2039728,
    "hits" : [
      {
        "_index" : "nested_test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.2039728,
        "_source" : {
          "name" : "php",
          "related" : [
            {
              "name" : "javascript",
              "count" : 9141
            }
          ]
        }
      }
    ]
  }
}

Can anyone point out what it is that I am doing wrong?

Upvotes: 1

Views: 290

Answers (1)

Val
Val

Reputation: 217304

Great start!! You simply need to ask for nested inner hits only:

curl -X GET http://localhost:9200/nested_test/_search?pretty=true -H 'Content-Type: application/json' -d '{
  "_source": {
     "_excludes": ["related"]
  },
  "query": {
    "nested": {
      "path": "related",
      "query": {
        "match": {
          "related.name": "javascript"
        }
      },
      "inner_hits": {}                   <--- add this
    }
  }
}'

Also note that I'm excluding the "related" field from returning in the _source document, because you'll get the inner hits you're after in the fields section (sibling to _source).

Upvotes: 2

Related Questions