Search code examples
elasticsearchnestelasticsearch-6

NEST elastic sort by filtered nested documents


I'm having a hard time in translating elastic query to c# Nest equivalent.

here is my elastic query

   "from":0,
   "size":15,
   "sort":[  
      {  
        "tags.date" :{
            "order" : "desc",
            "nested" : {
                "path" : "tags",
                "filter" : {
                    "term" : {"tags.id" : 1}
                }
            }
        }

      }
   ],

When I try this with C# Nest 6.2.0

        .Fomm(0)
        .Size(15)
        .Sort(s => s
            .Descending(sdf => sdf.Tags.First().Date)
            .Field(ff => ff
                .Nested(nstd => nstd
                    .Path(nsp => nsp.Tags)
                    .Filter(f2 => f2
                        .Term(sft => sft
                            .Field(a1 => a1
                                .Tags.First().Id)
                            .Value(1)
                        )
                    )
                )
            )
        )

it produces

   "from":0,
   "size":15,
   "sort":[  
      {  
         "tags.date":{  
            "order":"desc"
         }
      }
   ],

how can I mace it to apply filter on nested documents? What I'm I missing here?


Solution

  • The sort order and target field for the nested sort need to be inside the nested sort call. For example, given the following model

    public class Person 
    {
        public IEnumerable<Tag> Tags {get;set;}
    }
    
    public class Tag 
    {
        public int Id {get;set;}    
        public DateTime Date {get;set;}
    }
    

    This would look like

    var client = new ElasticClient(settings);
    
    var searchResponse = client.Search<Person>(s => s
        .From(0)
        .Size(15)
        .Sort(so => so
            .Field(f => f
                .Field(ff => ff.Tags.First().Date)
                .Order(Nest.SortOrder.Descending)
                .Nested(n => n
                    .Path(p => p.Tags)
                    .Filter(fi => fi
                        .Term(sft => sft
                            .Field(ff => ff.Tags.First().Id)
                            .Value(1)
                        )
                    )
                )
            )
        )
    );
    

    which yields

    {
      "from": 0,
      "size": 15,
      "sort": [
        {
          "tags.date": {
            "nested": {
              "filter": {
                "term": {
                  "tags.id": {
                    "value": 1
                  }
                }
              },
              "path": "tags"
            },
            "order": "desc"
          }
        }
      ]
    }