How to search in ElasticSearch nested objects using NEST How to search in ElasticSearch nested objects using NEST elasticsearch elasticsearch

How to search in ElasticSearch nested objects using NEST


Try to use nested query.

Let me index some data for test purpose:

client.Index(new Person{    Id = 1,     Car = new List<NestedType> {new NestedType {Carname = "car1"}}});client.Index(new Person{    Id = 2,    Car = new List<NestedType> {new NestedType {Carname = "car1"}, new NestedType {Carname = "car2"}}});client.Index(new Person{    Id = 3,    Car = new List<NestedType> { new NestedType {Carname = "car2"}}});client.Refresh();

Now, try this nested query:

var searchResponse = client.Search<Person>(s =>    s.Query(q => q        .Nested(n => n            .Path(p => p.Car)            .Query(qq => qq.Match(m => m.OnField(f => f.Car.First().Carname).Query("car2"))))));

Search result:

{   "took": 10,   "timed_out": false,   "_shards": {..},   "hits": {      "total": 2,      "max_score": 1.4054651,      "hits": [         {            "_index": "my_index",            "_type": "person",            "_id": "2",            "_score": 1.4054651,            "_source": {               "id": 2,               "car": [                  {                     "carname": "car1",                     "carNo": 0                  },                  {                     "carname": "car2",                     "carNo": 0                  }               ]            }         },         {            "_index": "my_index",            "_type": "person",            "_id": "3",            "_score": 1,            "_source": {               "id": 3,               "car": [                  {                     "carname": "car2",                     "carNo": 0                  }               ]            }         }      ]   }}

Hope it helps you.

UPDATE

Including your formatting:

var searchResponse = client.Search<person>(s =>    s.Query(q => q        .Nested(n => n            .Path(p => p.car)            .Query(qq => qq.Match(m => m.OnField(f => f.car.First().carname).Query("car2"))))));

UPDATE2

Based on your update, try this query:

var searchResponse = client.Search<Person>(s => s    .Query(query => query.Filtered(filtered => filtered        .Query(q => q.MatchAll())        .Filter(f => f.Nested(nf => nf            .Path(p => p.Car)            .Filter(filter => filter                .And(                    f1 => f1.Term(t => t.Car.First().Carname, "audi"),                    f2 => f2.Term(t => t.Car.First().Color, "purple")))             )))));

which produces this query to elasticsearch:

{  "query": {    "filtered": {      "query": {        "match_all": {}      },      "filter": {        "nested": {          "filter": {            "and": {              "filters": [                {                  "term": {                    "car.carname": "audi"                  }                },                {                  "term": {                    "car.color": "purple"                  }                }              ]            }          },          "path": "car"        }      }    }  }}

UPDATE3

With inner hits:

var searchResponse = client.Search<Person>(s => s    .Source(false)    .Query(query => query.Filtered(filtered => filtered        .Query(q => q.MatchAll())        .Filter(f => f.Nested(nf => nf            .InnerHits()            .Path(p => p.Car)            .Filter(filter => filter                .And(                    f1 => f1.Term(t => t.Car.First().Carname, "audi"),                    f2 => f2.Term(t => t.Car.First().Color, "purple")))            )))));

Note: there was bug in elasticsearch 1.5.0 regarding inner hits and filter. Have a look.Let me know if you need help with retrieving inner hits.