【问题标题】:Combining Search Across Multiple Geolocations in Multiple Indices在多个索引中组合跨多个地理位置的搜索
【发布时间】:2016-09-25 17:30:58
【问题描述】:

恐怕我不知道用什么术语来简洁地描述我正在尝试做的事情,但我会解释一下我目前正在做什么以及我想做什么。我正在尝试将两个搜索查询合并到一个查询中,从一个索引中获取地理点数据以使用搜索参数在第二个索引/文档类型中进行搜索。

我目前的 ES 设置:

索引和文档类型:

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

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

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

我目前的流程:

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

2) 系统获取邮编,搜索匹配结果,从locations.UK_postcode中获取geo_point经纬度数据。

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

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

我的问题:

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

【问题讨论】:

  • 距离总是一样吗?即,当环顾邮政编码时,您是否总是查看(例如)5 公里的邮政编码位置? (因为我们在谈论geo_distance
  • 不是距离是用户提供的搜索变量。
  • 所以他们制定了诸如“让我找到所有名称以 'Comp' 开头并且位于邮政编码 ABC123 周围 11.5 公里的客户”之类的查询?
  • 用户如何选择距离?是否有预定义距离的选择列表?
  • 他们输入一个代表英里数的浮点数。

标签: elasticsearch


【解决方案1】:

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

主要思想是:

  1. 在您的locations 索引中存储每个邮政编码和每个预定义距离的circle 类型的geo_shape
  2. 在您的 accounts 索引中为您的客户位置存储类型为 Pointgeo_shape
  3. 创建circle 类型的geo_shape 查询,该查询将利用预索引的邮政编码形状。

举个简单的例子,你会有这样的:

A.创建邮政编码位置索引:

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

B.创建客户位置索引

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

C.为“M32 0JG”创建半径为 1、2、3 英里的示例邮政编码圆

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

D.创建非常接近“M32 0JG”的示例客户端

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

E.查询所有名称与“big”匹配且位于邮政编码“M32 0JG”半径2英里内的所有客户

POST /accounts/client/_search
{
  "bool": {
    "must": [
      {
        "match": {
          "name": "big"               <--- free text name match
        }
      }
    ],
    "filter": {
      "geo_shape": {
        "location": {
          "indexed_shape": {
            "id": "M320JG-2",         <--- located within two miles of M32 0JG
            "type": "UK_postcode",
            "index": "locations",
            "path": "location"
          }
        }
      }
    }
  }
}

【讨论】:

  • 我看到了你的思路,我想知道我是否将每个邮政编码的 id 设置为实际的邮政编码而不是默认值。然后根据具有匹配ID(或邮政编码)的文档的locations.UK_postcode.location值过滤客户端距离。
  • 如果您使用通用 ID(例如邮政编码本身)索引您的邮政编码文档,那么获取位置当然更容易,即您不必搜索它,只需获取它。不过,这仍然是两个操作。
  • 嗯,谢谢你的帮助,你肯定给我指出了正确的方向。我认为这将是解决问题的方法,我需要获取邮政编码,然后将其位置值用作“距客户端位置的距离”的搜索变量。我太执着于搜索邮政编码数据,而这是获取邮政编码数据的问题。
  • 很高兴它能帮助您找到解决方案。在我这边,我专注于完全摆脱第二步(无论是搜索还是 GET)。
猜你喜欢
  • 2019-03-07
  • 2016-04-30
  • 1970-01-01
  • 2019-03-01
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
相关资源
最近更新 更多