Elasticsearch以不同的排序顺序获得距离

时间:2015-03-05 09:02:27

标签: c# elasticsearch nest

背景:

我们有以下要求:

  
      
  1. 应返回数据匹配关键字。
  2.   
  3. 数据包含经度和纬度字段,结果应该接近指定的lat long。
  4.   
  5. 返回的结果应包含距离字段,该字段指定数据中包含的给定lat long和lat long之间的距离。
  6.   
  7. 应根据MultiMatch分数对数据进行排序。
  8.   

阅读此链接中的教程Spatial Search ElasticSearch tutorial我在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))))));

根据教程,我必须使用SortGeoDistance方法来获得结果的距离。使用SortGeoDistance会根据距离对结果进行排序,但需要根据MultiMatch得分对结果进行排序。

1 个答案:

答案 0 :(得分:1)

以下Stackoverflow answer显示了如何在不使用排序的情况下获得距离。

以下是C#等同的答案。

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))))));