Elasticsearch进阶笔记第三十八篇

121 阅读3分钟

Elasticsearch高手进阶篇(78)

elasticsearch高手进阶_学习使用geo point地理位置数据类型

es支持基于地理位置的搜索

举个例子,比如说,我们后面就会给大家演示一下,你现在如果说做了一个酒店o2o app,让你的用户在任何地方,都可以根据当前所在的位置,找到自己身边的符合条件的一些酒店,那么此时就完全可以使用es来实现,非常合适

我现在在上海某个大厦附近,我要搜索到距离我2公里以内的5星级的带游泳池的一个酒店s,用es就完全可以实现类似这样的基于地理位置的搜索引擎

建立geo_point类型的mapping

第一个地理位置的数据类型,就是geo_point,geo_point,说白了,就是一个地理位置坐标点,包含了一个经度,一个维度,经纬度,就可以唯一定位一个地球上的坐标

 PUT /waws_index 
 {
   "mappings": {
     "waws_type": {
       "properties": {
         "location": {
           "type": "geo_point"
         }
       }
     }
   }
 }
写入geo_point的3种方法
 PUT /waws_index/waws_type/1
 {
   "text": "Geo-point as an object",
   "location": { 
     "lat": 41.12,
     "lon": -71.34
   }
 }
  • latitude:维度
  • longitude:经度

我们这里就不用去关心,这些坐标到底代表什么地方,其实都是我自己随便写的,只要能够作为课程,给大家演示清楚就可以了,自己去找一些提供地理位置的一些公司,供应商,api,百度地图,也是提供各个地方的经纬度的

不建议用下面两种语法

 PUT /waws_index/waws_type/2
 {
   "text": "Geo-point as a string",
   "location": "41.12,-71.34" 
 }
 
 PUT /waws_index/waws_type/4
 {
   "text": "Geo-point as an array",
   "location": [ -71.34, 41.12 ] 
 }
根据地理位置进行查询

最最简单的,根据地理位置查询一些点,比如说,下面geo_bounding_box查询,查询某个矩形的地理位置范围内的坐标点

 GET /waws_index/waws_type/_search 
 {
   "query": {
     "geo_bounding_box": {
       "location": {
         "top_left": {
           "lat": 42,
           "lon": -72
         },
         "bottom_right": {
           "lat": 40,
           "lon": -74
         }
       }
     }
   }
 }
 
 {
   "took": 38,
   "timed_out": false,
   "_shards": {
     "total": 5,
     "successful": 5,
     "failed": 0
   },
   "hits": {
     "total": 3,
     "max_score": 1,
     "hits": [
       {
         "_index": "waws_index",
         "_type": "waws_type",
         "_id": "2",
         "_score": 1,
         "_source": {
           "text": "Geo-point as a string",
           "location": "41.12,-71.34"
         }
       },
       {
         "_index": "waws_index",
         "_type": "waws_type",
         "_id": "4",
         "_score": 1,
         "_source": {
           "text": "Geo-point as an array",
           "location": [
             -71.34,
             41.12
           ]
         }
       },
       {
         "_index": "waws_index",
         "_type": "waws_type",
         "_id": "1",
         "_score": 1,
         "_source": {
           "text": "Geo-point as an object",
           "location": {
             "lat": 41.12,
             "lon": -71.34
           }
         }
       }
     ]
   }
 }

比如41.12,-71.34就是一个酒店,然后我们现在搜索的是从42,-72(代表了大厦A)和40,-74(代表了马路B)作为矩形的范围,在这个范围内的酒店,是什么

Elasticsearch高手进阶篇(79)

elasticsearch高手进阶_酒店o2o搜索案例以及搜索指定区域内的酒店

稍微真实点的案例,酒店o2o app作为一个背景,用各种各样的方式,去搜索你当前所在的地理位置附近的酒店

搜索指定区域范围内的酒店,比如说,我们可以在搜索的时候,指定两个地点,就要在东方明珠大厦和上海路组成的矩阵的范围内,搜索我想要的酒店

  • 建立mapping
 PUT /waws_hotel_app
 {
     "mappings": {
         "hotels": {
             "properties": {
                 "pin": {
                     "properties": {
                         "location": {
                             "type": "geo_point"
                         }
                     }
                 }
             }
         }
     }
 }
  • 添加数据
 PUT /waws_hotel_app/hotels/1
 {
     "name": "喜来登大酒店",
     "pin" : {
         "location" : {
             "lat" : 40.12,
             "lon" : -71.34
         }
     }
 }
  • 矩形内搜索数据
 GET /waws_hotel_app/hotels/_search
 {
   "query": {
     "bool": {
       "must": [
         {
           "match_all": {}
         }
       ],
       "filter": {
         "geo_bounding_box": {
           "pin.location": {
             "top_left" : {
                 "lat" : 40.73,
                 "lon" : -74.1
             },
             "bottom_right" : {
                 "lat" : 40.01,
                 "lon" : -71.12
             }
           }
         }
       }
     }
   }
 }
 
 {
   "took": 10,
   "timed_out": false,
   "_shards": {
     "total": 5,
     "successful": 5,
     "failed": 0
   },
   "hits": {
     "total": 1,
     "max_score": 1,
     "hits": [
       {
         "_index": "waws_hotel_app",
         "_type": "hotels",
         "_id": "1",
         "_score": 1,
         "_source": {
           "name": "喜来登大酒店",
           "pin": {
             "location": {
               "lat": 40.12,
               "lon": -71.34
             }
           }
         }
       }
     ]
   }
 }
  • 三角形内搜索
 GET /waws_hotel_app/hotels/_search 
 {
   "query": {
     "bool": {
       "must": [
         {
           "match_all": {}
         }
       ],
       "filter": {
         "geo_polygon": {
           "pin.location": {
             "points": [
               {"lat" : 40.73, "lon" : -74.1},
               {"lat" : 40.01, "lon" : -71.12},
               {"lat" : 50.56, "lon" : -90.58}
             ]
           }
         }
       }
     }
   }
 }
 
 {
   "took": 57,
   "timed_out": false,
   "_shards": {
     "total": 5,
     "successful": 5,
     "failed": 0
   },
   "hits": {
     "total": 1,
     "max_score": 1,
     "hits": [
       {
         "_index": "waws_hotel_app",
         "_type": "hotels",
         "_id": "1",
         "_score": 1,
         "_source": {
           "name": "喜来登大酒店",
           "pin": {
             "location": {
               "lat": 40.12,
               "lon": -71.34
             }
           }
         }
       }
     ]
   }
 }

我们现在要指定东方明珠大厦,上海路,上海博物馆,这三个地区组成的多边形的范围内,我要搜索这里面的酒店