• [ElasticSearch] 空间搜索 (一)


    依据索引文档的地理坐标来进行搜索。Elasticsearch 也可以处理这种搜索。——空间搜索

    一、为空间搜索准备映射

    PUT my_space_test
    {
      "mappings": {
        "poi": {
          "properties": {
            "name": {
              "type": "string"
            },
            "locationpoint": {
              "type":"geo_point"  //随意的地理坐标
            },
            "locationshape": {
              "type": "geo_shape"  //随意的地理形状
            }
          }
        }
      }
    }


    二、批量加入数据

    POST my_space_test/poi/_bulk
    {"index":{"_id":1}}
    {"name":"New York","locationpoint":"40.664167, -73.938611","locationshape":{"type":"polygon","coordinates":[[[4.8833,52.38617],[4.87463,52.37254],[4.87875,52.36369],[4.8833,52.38617]]]}}
    {"index":{"_id":2}}
    {"name":"London","locationpoint":[-0.1275,51.5072222],"locationshape":{"type":"polygon","coordinates":[[[0,0],[4.87463,52.37254],[4.87875,52.36369],[0,0]]]}}
    {"index":{"_id":3}}
    {"name":"Moscow","locationpoint":{"lat":55.75,"lon":37.616667},"locationshape":{"type":"polygon","coordinates":[[[22,22],[4.87463,52.37254],[4.87875,52.36369],[22,22]]]}}
    {"index":{"_id":4}}
    {"name":"Sydney","locationpoint":"-33.859972, 151.211111","locationshape":{"type":"polygon","coordinates":[[[4.8833,52.38617],[4.87463,52.37254],[4.87875,52.36369],[4.8833,52.38617]]]}}
    {"index":{"_id":5}}
    {"name":"Sydney","locationpoint":"eycs0p8ukc7v","locationshape":{"type":"polygon","coordinates":[[[4.8833,52.38617],[4.87463,52.37254],[4.87875,52.36369],[4.8833,52.38617]]]}}
    细致观看locationpoint字段能够看到坐标能够使用多种形式来赋值,能够使用字符串、数组(仅仅能包括两个数值)、一个对象、地理散列值等来提供经纬度。

    详细每种方式可能略有不同,详细使用再查相关资料。

    再来看一下。locationshape,其形式就更加多样了,能够是一个点 ,即为一组数值对 [ 经度,维度 ] ,也能够是一个框 [ [左。上], [右,下] ],还能够是多边形。可是必须保证第一个坐标和最后一个坐标是同样的,从而保证是一个闭合的图形。[ [ [1,1],[2,2], [3,4] ,[1,1] ] ] ,能够发现多边形的定义中其能够是多个多边形,是一个可扩展的数组。

    三、查询方式

    3.1 基于距离排序

    GET my_space_test/poi/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "_geo_distance": {
            "locationpoint": {
              "lat": 48.8567,
              "lon": 2.3508
            },
            "unit": "km",
            "order": "asc"
          }
        }
      ]
    }
    GET my_space_test/poi/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
            "_geo_distance":<{
            "locationpoint": [       //或者是:"locationpoint":" 48.8567,2.3508"
              2.3508,
              48.8567
            ],
            "unit": "km",
            "order": "asc"
          }
        }
      ]
    }
    以上查询的结果是一样的(注意数组和字符串坐标的位置顺序是不同的)通过距离坐标点 [  2.3508,48.8567 ]的大小来对查询文档进行排序。这在实际搜索中很实用,能够返回临近的一些坐标点。

    3.2 边界框过滤(获得包括在指定区域内文档)

    "query": {
        "filtered": {
          "filter": {
            "bool": {
              "should": [
                {
                 "geo_bounding_box": {
                    "locationpoint": {
                      "top_left": "52.4796,-1.903",
                      "bottom_right": "48.8567,2.3508"
                    }
                  }
                },
                {
                 "geo_distance":{
                    "distance": 500,
                    "distance_unit": "km",
                    "locationpoint": "48.8567,2.3508"
                  }
                }]}}}}

    示意图 1

    返回的文档就像是包括在矩形和圆形中的蓝色点,红色点用来确定边框,红色线段确定距离范围。在图形之外的点就被过滤掉了。以上都是针对类型为geo_point
    以下我们来看一下geo_shape类型是怎样使用的?
    "query": {
        "filtered": {
          "filter": {
            "bool": {
              "should": [
                {
                  "geo_shape": {
                    "locationshape": {
                      "indexed_shape": {             //使用已经索引的形状
                        "index": "my_space_test",
                        "type": "poi",
                        "id": "4",
                        "path": "locationshape"
                      },
                      "relation": "within"
                    }
                  }
                },
                {
                  "geo_shape": {
                    "locationshape": {          //自己定义形状——圆
                      "shape": {
                        "type": "circle",   
                        "radius": "1km",
                        "coordinates": [
                          -45,
                          45
                        ]
                      },
                      "relation": "within"
                    }
                  }
                },{
                  "geo_shape": {
                    "locationshape": {
                      "shape": {
                        "type": "envelope",     //自己定义的形状包络线,即:box(矩形)
                        "coordinates": [
                          [
                            -45,
                            45
                          ],
                          [
                            45,
                            -45
                          ]
                        ]
                      },
                      "relation": "within"
                    }
                  }
                },{
                  "geo_shape": {
                    "locationshape": {       //自己定义的多边形。一定要注意,多边形的定义是包括在一个数组中的,是一个可扩展的数组
                      "shape": {
                        "type": "polygon",
                        "coordinates": [[[1,1],[2,3],[4,2],[1,1]]]
                      },
                      "relation": "within"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    首先来说,过滤查询的字段locationshap 中包括多种形状类型。有点、包络线、多边形、甚至说多个多边形
    以上的查询是看那些形状位于所查询的形状之内。
    我们再来个示意图吧,这样好理解一些。



    示意图2

    比方说,我们能够定义一个中国的多边形。然后查找那些城市是位于中国的。这些城市也能够是多边形,当然也能够用一个点来定义,通过这种过滤方式都能够准确的找到。

    怎么样?ES是不是非常炫?革命尚未成功,同志仍需努力!坚持你才干看到最美的风景,即便一路上会有荆棘。接下来看看。空间搜索相应的高亮和聚合。待续……










  • 相关阅读:
    vim 配合管道过滤多行记录
    SpringBoot自动配置原理
    SpringBoot零XML配置的Spring Boot Application
    SpringBoot快速开始Hello World
    Java反射机制
    Java网络编程
    Java JDBC
    Java泛型
    Java I/O
    Java集合
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7267731.html
Copyright © 2020-2023  润新知