2

Background:

We have requirement for following:

  1. Data matching keyword should be returned.
  2. Data has longitude and latitude fields, result should be near specified lat long.
  3. Returned result should contain distance field, which specified distance between given lat long and lat long contained in data.
  4. Data should be sorted accouding to MultiMatch score.

Reading the tutorial in this link Spatial Search ElasticSearch tutorial I have constructed following query in C#.

 var res = await _elasticClient
            .SearchAsync<Results>(
                s =>
                    s.Type("Data")
                        .Skip(skip)
                        .Take(limit)
                      .SortGeoDistance(es => 
                            es.Ascending().OnField("Coordinates").Unit(GeoUnit.Kilometers).PinTo(lat,lng))
                      .Query(
                        q1 =>
                            q1.Filtered(
                                f1 =>
                                    f1.Query(q2 => q2.MultiMatch(mm => mm.OnFields(MultiMatchFieldsArray)
                                    .Query(keyword)
                                    .Type(TextQueryType.MostFields)))
                                    .Filter(f2 => f2.GeoDistance("Coordinates",gf => gf.Distance(10,GeoUnit.Kilometers)
                                    .Location(lat,lng))))));

According to tutorial I have to use SortGeoDistance method to get distance in result. Using SortGeoDistance will sort result according to distance, but in need result to be sorted according to MultiMatch score.

eckes
  • 10,103
  • 1
  • 59
  • 71
Pavan Kumar
  • 1,715
  • 1
  • 24
  • 48

1 Answers1

2

Following Stackoverflow answer shows how to get distance without using sort.

Below is C# equivalent of the answer.

var esSearch = await _elasticClient
            .SearchAsync<Results>(
                s =>
                    s.Type("Data")
                      .Skip(skip)
                      .Take(limit)
                      .Fields("_source")
                      .ScriptFields(sf => sf.Add("Distance", des => des.Params(param => param.Add("lat", lat).Add("lon", lng)).Script("doc[\u0027Coordinates\u0027].arcDistanceWithDefault(lat,lon,-1)")))
                      .Query(
                        q1 =>
                            q1.Filtered(
                                f1 =>
                                    f1.Query(q2 => q2.MultiMatch(mm => mm.OnFields(MultiMatchFields)
                                    .Query(keyword)
                                    .Type(TextQueryType.MostFields)))
                                    .Filter(f2 => f2.GeoDistance("Coordinates",gf => gf.Distance(10,GeoUnit.Kilometers)
                                    .Location(lat,lng))))));
Community
  • 1
  • 1
Pavan Kumar
  • 1,715
  • 1
  • 24
  • 48
  • Thanks for your answer. In the trace I can see that the values are filled. Unfortunately the property I defined in my model is not set. Did you made further configurations like in your mapping? – core Jul 28 '15 at 09:08