地理坐标盒模型过滤器 (geo_bounding_box Filter)edit

这(geo_bounding_box)是目前为止最有效的地理坐标过滤器了,因为它计算起来非常简单。 你指定一个矩形的顶部底部左边界右边界坐标,然后过滤器只需判断坐标的经度是否在左右边界之间,纬度是否在上下边界之间:

GET /attractions/restaurant/_search
{
  "query": {
    "filtered": {
      "filter": {
        "geo_bounding_box": {
          "location": { 
            "top_left": {
              "lat":  40.8,
              "lon": -74.0
            },
            "bottom_right": {
              "lat":  40.7,
              "lon": -73.0
            }
          }
        }
      }
    }
  }
}

这些坐标也可以用 bottom_lefttop_right 来表示。(球面上任意两个经纬度都不同的点就能确定一个矩形)

优化盒模型edit

geo_bounding_box不需要把所有坐标点都加载到内存里。因为它要做的只是简单判断latlon值是否在给定的范围内,它可以用倒排索引执行一个(性能杠杠的)范围(range)过滤。

要使用这种优化方式,需要把geo_point字段用latlon 的方式分别映射到索引中:

PUT /attractions
{
  "mappings": {
    "restaurant": {
      "properties": {
        "name": {
          "type": "string"
        },
        "location": {
          "type":    "geo_point",
          "lat_lon": true 
        }
      }
    }
  }
}

location.latlocation.lon 字段将被分别索引。它们可以被用于检索,但是不会在检索结果中返回。

然后,查询时你需要告诉 Elasticesearch 使用已索引的latlon

GET /attractions/restaurant/_search
{
  "query": {
    "filtered": {
      "filter": {
        "geo_bounding_box": {
          "type":    "indexed", 
          "location": {
            "top_left": {
              "lat":  40.8,
              "lon": -74.0
            },
            "bottom_right": {
              "lat":  40.7,
              "lon":  -73.0
            }
          }
        }
      }
    }
  }
}

设置type参数值为indexed(替代默认值memory)来明确告诉 Elasticsearch 对这个过滤器使用倒排索引。

geo_point 类型的字段可以包含多个地理坐标点,但是针对经度纬度分别索引的这种优化方式只对包含单个坐标点的字段有效。