【问题标题】:ElasticSearch geo distance filter with multiple locations in array - possible?阵列中具有多个位置的 ElasticSearch 地理距离过滤器 - 可能吗?
【发布时间】:2013-04-13 08:49:07
【问题描述】:

假设我们在 ElasticSearch 索引中有一堆文档。每个文档都有多个位置在一个数组中,像这样:

{
  "name": "foobar",
  "locations": [
    {
      "lat": 40.708519,
      "lon": -74.003212
    },
    {
      "lat": 39.752609,
      "lon": -104.998100
    },
    {
      "lat": 51.506321,
      "lon": -0.127140
    }
  ]
}

根据ElasticSearch reference guide

geo_distance 过滤器可以处理多个位置/点 每个文件。一旦单个位置/点与过滤器匹配, 文档将包含在过滤器中。

那么,是否可以创建一个地理距离过滤器来检查数组中的所有位置?

不幸的是,这似乎不起作用:

{
  "filter": {
    "geo_distance": {
      "distance": "100 km",
      "locations": "40, -105"
    }
  }
}

抛出“QueryParsingException[[myIndex] failed to find geo_point field [locations]”,因为locations 不是单个geo_point,而是geo_points 的数组。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您是否为文档指定了geo_point mapping

    curl -XDELETE 'http://localhost:9200/twitter/'
    curl -XPUT 'http://localhost:9200/twitter/'
    
    curl -XPUT 'http://localhost:9200/twitter/tweet/_mapping' -d '
    {
        "tweet" : {
            "properties" : {
                "locations" : {"type" : "geo_point"}
            }
        }
    }'
    
    curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '
    { 
        "user": "kimchy", 
        "postDate": "2009-11-15T13:12:00", 
        "message": "Trying out Elastic Search, so far so good?",
        "locations" : [{
            "lat" : 50.00,
            "lon" : 10.00
        },
        {
            "lat" : 40.00,
            "lon" : 9.00
        }]
    }'
    
    curl -XPUT 'http://localhost:9200/twitter/tweet/2' -d '
    { 
        "user": "kimchy", 
        "postDate": "2009-11-15T13:12:00", 
        "message": "Trying out Elastic Search, so far so good?",
        "locations" : [{
            "lat" : 30.00,
            "lon" : 8.00
        },
        {
            "lat" : 20.00,
            "lon" : 7.00
        }]
    }'
    
    curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '{
        "query": {
            "filtered" : {
                "query" : {
                    "match_all" : {}
                },
                "filter" : {
                    "geo_distance" : {
                        "distance" : "20km",
                        "tweet.locations" : {
                            "lat" : 40.00,
                            "lon" : 9.00
                        }
                    }
                }
            }
        }
    }'
    

    【讨论】:

    • 那么它应该可以工作,请参阅我的示例。你用的是哪个 ES 版本?我在 0.20.6 上测试过。
    • 实际上,在删除原始索引后,它确实现在可以工作了。指定一个 geo_point 映射,然后只插入一个位置数组就可以了,我之前的映射太复杂了。非常感谢!
    • 这是否适用于快速 bbox 过滤器 geo_bounding_boxgeo_distance 可能更慢(因为半径距离数学)。我将尝试使用{"type": "geo_point", "lat_lon": true}
    • 您好,该示例现在在 ES v1.7.3 中不起作用。如果我插入值数组,位置字段始终为空。有什么变化吗?
    【解决方案2】:

    对于 Elasticsearch 5.1 版,对于上述相同的索引,查询将如下所示,

    curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '
    {
        "query": {
            "bool": {
                "must": {
                    "match_all": {}
                },
                "filter": {
                    "geo_distance": {
                        "distance": "200km",
                        "locations": {
                            "lat": 40.00,
                            "lon": 9.00
                        }
                    }
                }
            }
        }
    }'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      相关资源
      最近更新 更多