【问题标题】:ElasticSearch GeoDistance QueryElasticSearch 地理距离查询
【发布时间】:2014-04-13 07:58:24
【问题描述】:

我正在像这样在 python 中使用地理距离查询

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "geo_distance": {
          "distance": "20miles",
          "location": {
            "lat": 51.512497,
            "lon": -0.052098
          }
        }
      }
    }
  }
} 

它工作正常。我的问题是如何在文档中给“距离”一个值。对于每条记录,我的索引中有一个像 distance: 50 这样的字段,我想将它用作地理距离中的距离值。我试过"distance":doc['distance'].value,但它不起作用。

【问题讨论】:

    标签: python elasticsearch pyes


    【解决方案1】:

    普通查询和过滤器不希望将脚本放置在其中。

    假设您存储了一个字段名称为locationgeo_point,那么您希望使用doc['field_name'].distanceInMiles(lat, lon) 来使用script filter(而不是distance(lat, lon),因为标准单位是meters截至v1.0.0):

    {
      "filtered" : {
        "query" : { "match_all" : { } },
        "filter" : {
          "script" : {
            "script" :
              "doc['location'].distanceInMiles(lat, lon) < doc['distance'].value",
            "params" : {
              "lat" : 51.512497,
              "lon" : -0.052098
            }
          }
        }
      }
    }
    

    如果您正在运行一个 Elasticsearch 实例,它使用以前的标准单位 miles(pre-v1.0.0),那么您可以使用普通的 distance 函数(或如果您的 distance 单位恰好在现在的标准 meters as-of v1.0.0):

    {
      "filtered" : {
        "query" : { "match_all" : { } },
        "filter" : {
          "script" : {
            "script" :
              "doc['location'].distance(lat, lon) < doc['distance'].value",
            "params" : {
              "lat" : 51.512497,
              "lon" : -0.052098
            }
          }
        }
      }
    }
    

    注意:您可以直接在脚本中提供 latlon 的值以进行一次性执行,但脚本被编译缓存,因此使用参数允许重用,因此速度更快首次使用后执行。

    如文档中所述,您可以通过在过滤器中添加"_cache" : true 来缓存过滤器的结果,但默认情况下缓存过滤器的结果。

    【讨论】:

    • 我试过但得到以下错误“查询[过滤(ConstantScore(ScriptFilter(doc['location'].distanceInMiles(lat, lon))))->cache(_type:users-schema )],from[0],size[10]: 查询失败 [无法执行主查询]]; 嵌套: PropertyAccessException[[错误: 无法解析方法: org.elasticsearch.index.fielddata.ScriptDocValues$GeoPoints.distanceInMiles( java.lang.Double, java.lang.Double) [arglength=2]] [Near : {... doc['location'].distanceInMile ....}] ^ [Line: 1, Column: 1]] ; }]"
    • 您使用的是什么版本的 Elasticsearch?该方法是在v1.0.0 in late December, 2013 中添加的。不过幸运的是,在 1.0 之前,默认单位已经是 miles(而不是 meters),因此您可以将方法从 distanceInMiles(lat, lon) 更改为 distance(lat, lon),它应该可以正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多