8. Elasticsearch 地理位置及搜索

1,649 阅读4分钟

两种数据类型:geo_point和geo_shape:地理位置类型,经纬度坐标

geo_point

经纬度坐标,只支持WGS84坐标系,坐标范围Lat值为[-90,90],Lon为[-180,180]

  • latitude:维度 缩写:lat
  • longitude:经度 缩写:lon
  • ignore_malformed:则忽略格式错误的地理位置。如果false(默认)
  • 五种存储方式
# 设置mapping
PUT geo_point
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "location": {
        "type": "geo_point"
      }
    }
  }
}

#第一种
PUT geo_point/_doc/1
{
  "name": "天安门",
  "location": { 
    "lat": 40.12,
    "lon": -71.34
  }
}
#"lat,lon" 第二种
PUT geo_point/_doc/2
{
  "name": "前门",
  "location": "40.12,-72.34"
}
#[lon,lat]第三种
PUT geo_point/_doc/3
{
  "name": "后门",
  "location": [ -75.34,40.12]
}
#WKT
PUT geo_point/_doc/2
{
  "name": "前门",
  "location": "POINT (-72.34 40.12)"
}
#GEO哈希
#Geo哈希 https://www.cnblogs.com/LBSer/p/3310455.html

GET /geo_point/_mapping
GET /geo_point/_search

geo_shape

ES的特殊类型之一,用来描述复杂的几何图形的类型,比如点、线、面,多边形等二维几何模型。

  • GeoJSON:GeoJSON是一种用于编码各种地理数据结构的格式,支持以下几种几何类型:
    • Point:点
    • LineString:线段
    • Polygon:多边形
    • MultiPoint:多点
    • MultiLineString:多线段
    • MultiPolygon:多边形集合
    • Feature:具有其他属性的对象
  • WKT(Well-Known Text):POINT(125.6 10.1)
DELETE geo_shape
GET geo_shape/_mapping
PUT geo_shape
{
    "mappings": {
        "properties": {
            "location": {
                "type": "geo_shape"
            }
        }
    }
}

#储存一个点
POST /geo_shape/_doc/1
{
  "name":"中国 香海",
  "location":{
    "type":"point",
    "coordinates":[13.400544, 52.530286]
  }
}
#WKT方式
GET geo_shape/_doc/1
POST /geo_shape/_doc/1
{
  "name":"中国 香海",
  "location":"POINT (13.400544 52.530286)"
}

#储存一个线段
POST /geo_shape/_doc/2
{
  "name":"随意",
  "location":{
    "type":"linestring",
    "coordinates":[[13.400544, 52.530286],[-77.400544, 38.530286]]
  }
}
#WKT
POST /geo_shape/_doc/2
{
  "name": "随意",
  "location":"LINESTRING (13.400544 52.530286,-77.400544 38.530286)"
}

# 储存一个几何形状
POST /geo_shape/_doc/3
{
  "name": "河北省",
  "location": {
    "type": "polygon",
    "coordinates": [
      [
        [
          100,
          0
        ],
        [
          101,
          0
        ],
        [
          101,
          1
        ],
        [
          100,
          1
        ],
        [
          100,
          0
        ]
      ],
      [
        [
          100.2,
          0.2
        ],
        [
          100.8,
          0.2
        ],
        [
          100.8,
          0.8
        ],
        [
          100.2,
          0.8
        ],
        [
          100.2,
          0.2
        ]
      ]
    ]
  }
}
#WKT 方式
POST /geo_shape/_doc/3
{
    "location" : "POLYGON ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0))"
}

PUT _ingest/pipeline/polygonize_circles
{
  "description": "圆圈转换成多边形",
  "processors": [
    {
      "circle": {
        "field": "location",
        "error_distance": 0,
        "shape_type": "geo_shape"
      }
    }
  ]
}
POST /geo_shape/_doc/4?pipeline=polygonize_circles
{
   "name": "安全区",
    "location": {
        "type": "circle",
        "coordinates": [30.0, 10.0],
        "radius":"1m"
    }
}

四种查询

geo_bounding box query(矩形查询)

在同一个平面内,两个点确定一个矩形,搜索矩形内的坐标 参数:

  • top_left:矩形左上点坐标
  • bottom_right:矩形右上角表
#geo_bounding box query
GET /geo_point/_search
{
  "query": {
    "geo_bounding_box":{
      "location":{
        "top_left":{
          "lat": 50.73,
          "lon": -74.1
        },
        "bottom_right":{
          "lat": 30.01,
          "lon": -61.12
        }
      }
    }
  }
}

geo_distance query(半径查询)

以某个点为圆心查找指定半径的圆内的坐标。

  • distance:距离单位,默认是米,支持以下选项
    • Mile(英里):mi 或者 miles
    • Yard(码):yd 或者yards
    • Feet(英尺):ft 或者feet
    • Inch(英寸):in 或者inch
    • Kilometer(公里):km 或者kilometers
    • Meter(米):m后者meters
    • Centimeter(厘米):cm 或者centimeters
    • Millimeter(毫米):mm 或者millimeters
    • Nautical mile(海里):NM, nmi, 或者nauticalmiles
  • distance_type:计算距离的方式
    • arc(默认值):更准确,但是速度慢
    • plane:(更快,但在长距离和极点附近不准确)
# point 查询
GET /geo_point/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "geo_distance": {
            "distance": "500km",
            "location": {
              "lat": 40,
              "lon": -71
            }
          }
        }
      ]
    }
  }
}

geo_polygon query(多边形)

查找给定多个点连成的多边形内的坐标。
一个封闭的多边形,其第一个点和最后一个点必须匹配,因此需要n + 1顶点创建一个带n边的多边形和一个最小的4顶点。

#多边形查找
GET geo_point/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": [
        {
          "geo_polygon": {
            "location": {
              "points": [
                {
                  "lat": 40,
                  "lon": -170
                },
                {
                  "lat": 40,
                  "lon": -171
                },
                {
                  "lat": 50,
                  "lon": -171.1
                },
                {
                  "lat": 40,
                  "lon": -170
                }
              ]
            }
          }
        }
      ]
    }
  }
}

geo_shape query(特殊几何形状)

支持指定几何图形相交、包含或是不相交等图形检索

  • Inline Shape Definition:内联形状 自己定义的形状包络线,即:box(矩形)
GET geo_shape/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "geo_shape": {
            "location": {
              "shape": {
                "type": "envelope",
                "coordinates": [
                  [
                    13,
                    53
                  ],
                  [
                    14,
                    52
                  ]
                ]
              },
              "relation": "within"
            }
          }
        }
      ]
    }
  }
}
  • Pre-Indexed Shape 使用已存在的数据,查询数据内的数据, 如:查询河南省内的旅游景点
  • id- 包含预索引形状的文档ID。
  • index- 索引的名称,其中预索引形状为:默认形状。
  • routing- 非必须。
  • path- 包含预索引形状的指定路径,默认形状。
GET /geo_shape/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_shape": {
          "location": {
            "indexed_shape": {
              "index": "geo_shape",
              "id": "4",
              "path": "location"
            },
            "relation": "within"
          }
        }
      }
    }
  }
}

Spatial Relations(空间关系)

  • INTERSECTS- (默认)返回其geo_shape字段与查询几何体相交的所有文档。
  • DISJOINT- 返回其geo_shape字段与查询几何图形无任何共同点的所有文档。
  • WITHIN- 返回其geo_shape字段在查询几何中的所有文档。
  • CONTAINS- 返回其geo_shape字段包含查询几何的所有文档。
PUT geo_shape_test
{
    "mappings": {
        "properties": {
            "location": {
                "type": "geo_shape"
            }
        }
    }
}

#存矩形
POST /geo_shape_test/_doc/A
{
  "location": {
    "type": "envelope",
    "coordinates": [[1,7],[6,1]]
  }
}
POST /geo_shape_test/_doc/B
{
  "location": {
    "type": "envelope",
    "coordinates": [[4,8],[8,5]]
  }
}
POST /geo_shape_test/_doc/C
{
  "location": {
    "type": "envelope",
    "coordinates": [[2,4],[4,2]]
  }
}

#P1
POST /geo_shape_test/_doc/P1
{
  "name":"P1",
  "location":{
    "type":"point",
    "coordinates":[3, 3]
  }
}
#P2
POST /geo_shape_test/_doc/P2
{
  "name":"P2",
  "location":{
    "type":"point",
    "coordinates":[5, 6]
  }
}
#P3
POST /geo_shape_test/_doc/P3
{
  "name":"P3",
  "location":{
    "type":"point",
    "coordinates":[7, 7]
  }
}
#P4
POST /geo_shape_test/_doc/P4
{
  "name":"P4",
  "location":{
    "type":"point",
    "coordinates":[3, 5]
  }
}
#P5
POST /geo_shape_test/_doc/P5
{
  "name":"P5",
  "location":{
    "type":"point",
    "coordinates":[7, 3]
  }
}


GET /geo_shape_test/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_shape": {
          "location": {
            "indexed_shape": {
              "index": "geo_shape_test",
              "id": "A",
              "path": "location"
            },
            "relation": "intersects"
          }
        }
      }
    }
  }
}

表示圆的多边形的精度定义为error_distance。这种差异越小,多边形越接近理想圆。下表是旨在帮助捕获在给定不同输入的情况下圆的半径如何影响多边形的边数的表格。最小边数为4,最大为1000。

ElasticSearch完整目录

1. Elasticsearch是什么
2.Elasticsearch基础使用
3.Elasticsearch Mapping
4.Elasticsearch 集群原理
5.Elasticsearch Scripts和读写原理
6.Elasticsearch 分词器
7.Elasticsearch TF-IDF算法及高级查询
8.Elasticsearch 地理位置及搜索
9.Elasticsearch ELK