结合多个索引中多个地理位置的搜索

时间:2016-05-27 11:32:23

标签: elasticsearch

我害怕我不知道简明扼要地描述我正在做什么的术语,但我会解释我目前在做什么以及我想做什么。我正在尝试将两个搜索查询聚合到一个查询中,从一个索引获取地理点数据以使用搜索参数在第二个索引/ doctype中进行搜索。

我目前的ES设置:

指数和DocTypes:

|- 1) locations
|---- 1a) UK_postcode

|- 2) accounts
|---- 2a) client

每个Doctypes都有一个字段名称“location”,它映射到GeoPoint类型。

我目前的流程:

1)用户根据关键字和距离位置(英国邮政编码)搜索客户。

2)系统获取邮政编码并搜索匹配结果,以从位置获取geo_point纬度和经度数据.UK_postcode。

3)系统使用提供的关键字和经纬度来搜索accounts.client index / doctype。

4)系统根据ES搜索结果向用户返回漂亮的结果。

我的问题:

第2步和第3步可以合并为一个搜索查询吗?如果是,我该怎么做?我想将邮政编码传递给搜索查询,并希望ES找到geo_point数据,以满足客户端doctype上地理距离查询的要求。

1 个答案:

答案 0 :(得分:1)

使用pre-indexed shapes,您绝对可以消除第2步。请注意,此解决方案仅适用于预定义的距离。

主要想法是:

  1. locations索引中存储geo_shape类型为circle的每个邮政编码和每个预定义的距离。
  2. accounts索引中存储geo_shape类型为Point的客户位置
  3. 创建类型geo_shape的{​​{1}}查询,该查询将利用预先编制索引的邮政编码形状。
  4. 作为一个简单的例子,你有这个:

    一个。创建邮政编码位置索引:

    circle

    B中。创建客户位置索引

    PUT /locations
    {
        "mappings": {
            "UK_postcode": {
                "properties": {
                    "location": { "type" : "geo_shape" }
                }
            }
        }
    }
    

    ℃。为“M32 0JG”创建1,2,3英里半径的样本邮政编码圈

    PUT /accounts
    {
        "mappings": {
            "client": {
                "properties": {
                    "name": { "type": "string" }
                    "location": { "type" : "geo_shape" }
                }
            }
        }
    }
    

    d。创建非常靠近“M32 0JG”的样本客户端

    PUT /locations/UK_postcode/M320JG-1
    {
        "location": {
            "type" : "circle",
            "coordinates" : [-2.30283674284007, 53.4556572899372],
            "radius": "1mi"
        }
    }
    
    PUT /locations/UK_postcode/M320JG-2
    {
        "location": {
            "type" : "circle",
            "coordinates" : [-2.30283674284007, 53.4556572899372],
            "radius": "2mi"
        }
    }
    
    # ... repeat until radius = 10
    

    电子。查询名称匹配“大”且位于邮编“M32 0JG”半径2英里内的所有客户

    PUT /accounts/client/1234
    {
        "name": "Big Corp"
        "location": {
            "type" : "point",
            "coordinates" : [-2.30293674284007, 53.4557572899372]
        }
    }