【问题标题】:Elasticsearch getting distance with different sort orderElasticsearch 以不同的排序顺序获取距离
【发布时间】:2015-03-05 09:02:27
【问题描述】:

背景:

我们有以下要求:

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

阅读此链接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 分数对结果进行排序。

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案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))))));
    

    【讨论】:

    • 感谢您的回答。在跟踪中,我可以看到值已填充。不幸的是,我在模型中定义的属性没有设置。您是否在映射中进行了进一步的配置?
    猜你喜欢
    • 2021-04-21
    • 2017-04-08
    • 2017-07-29
    • 2020-01-18
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    相关资源
    最近更新 更多