2

I am learning Elasticsearch so I am not sure if this query is correct. I have checked that the data is indexed, but I don't get any hits. What am I doing wrong? Shouldn't this get a hit on a car where the creator's name is steve?

builder
.startObject()
    .startObject("car")
        .field("type", "nested")
        .startObject("properties")
            .startObject("creators")
                .field("type", "nested")                    
            .endObject()                
        .endObject()
    .endObject()
.endObject();


{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "car.creators.name": "Steve"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

1 Answer 1

9

First of all, in order to search nested fields you need to use nested query:

curl -XDELETE localhost:9200/test
curl -XPUT localhost:9200/test -d '{
    "settings": {
        "index.number_of_shards": 1,
        "index.number_of_replicas": 0
    },
    "mappings": {
            "car": {
                "properties": {
                    "creators" : {
                        "type": "nested",
                        "properties": {
                            "name": {"type":"string"}
                        }
                    }
                }
            }
        }
    }
}
'
curl -XPOST localhost:9200/test/car/1 -d '{
    "creators": {
        "name": "Steve"
    }
}
'
curl -X POST 'http://localhost:9200/test/_refresh'
echo
curl -X GET 'http://localhost:9200/test/car/_search?pretty' -d '    {
    "query": {
        "nested": {
            "path": "creators",
            "query": {
                "bool": {
                    "must": [{
                        "match": {
                            "creators.name": "Steve"
                        }
                    }],
                    "must_not": [],
                    "should": []
                }
            }
        }
    },
    "from": 0,
    "size": 50,
    "sort": [],
    "facets": {}
}
'

If car.creators.name was indexed using standard analyzer then {"term": {"creators.name": "Steve"}} will not find anything because word Steve was indexed as steve and the term query doesn't performs analysis. So, it might be better to replace it with the match query {"match": {"creators.name": "Steve"}}.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks! I had to move the path field out of the query object though and insert "creators" in the path and only use creators.name in the term. Does that sound wrong or is it correct?
Yes, you are right. Path should be on the same level as query and should contain "car.creators". I have updated the example. Not sure about creators.name in the term. Is car a type in your case?
Yes, car is a type? Since I am learning about Elasticsearch would you mind explaining why I don't need it and you manage to get it working with it?
I was just confused. When I saw "type": "nested" under car I thought car is a field. If car is a type, you don't need "type": "nested" there and yes you need to use creators.name in query. I modified my example to use car as a type.
Type is optional in the "path" element. It can be there but because I already specified type on url it's unnecessary. Type shouldn't be present in the nested query.

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.