zoukankan      html  css  js  c++  java
  • [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是不是非常炫?革命尚未成功,同志仍需努力!坚持你才干看到最美的风景,即便一路上会有荆棘。接下来看看。空间搜索相应的高亮和聚合。待续……










  • 相关阅读:
    Maximum Flow Exhaustion of Paths Algorithm
    ubuntu下安装java环境
    visualbox使用(二)
    vxworks一个超级奇怪的错误(parse error before `char')
    February 4th, 2018 Week 6th Sunday
    February 3rd, 2018 Week 5th Saturday
    February 2nd, 2018 Week 5th Friday
    February 1st, 2018 Week 5th Thursday
    January 31st, 2018 Week 05th Wednesday
    January 30th, 2018 Week 05th Tuesday
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7267731.html
Copyright © 2011-2022 走看看