es地理位置之地理坐標(biāo)

??記得小時(shí)候去北京時(shí),關(guān)于北京城的地圖還賣(mài)兩塊錢(qián)一份,得益于科技的進(jìn)步,現(xiàn)在我們總是可以知道自己的準(zhǔn)確位置,比如距離自己 5 km 內(nèi)的餐館,距離自己最近的酒店等等。
??es 中不僅提供了地理位置的功能,還可以將地理位置、全文搜索、結(jié)構(gòu)化搜索和分析結(jié)合到一起。
??es提供了 兩種表示地理位置的方式:
??(1)用緯度-經(jīng)度表示的坐標(biāo)點(diǎn)使用 geo_point 字段類(lèi)型。
??(2) 以 GeoJSON 格式定義的復(fù)雜地理形狀,使用 geo_shape 字段類(lèi)型。
??當(dāng)然兩種方式有著不同的作用,geo_point計(jì)算距離某個(gè)坐標(biāo)點(diǎn)一定距離的所有坐標(biāo)點(diǎn),并根據(jù)坐標(biāo)點(diǎn)之間的距離進(jìn)行打分、或者聚合到顯示在地圖上的一個(gè)網(wǎng)絡(luò); 而 geo_shape完全是用來(lái)過(guò)濾的。他可以判斷兩個(gè)地理形狀是否有重合,或者一個(gè)地理形狀是否包含另一個(gè)地理形狀。

1. 經(jīng)緯度坐標(biāo)表示

??注意,地理坐標(biāo)點(diǎn)不能被自動(dòng)映射,必須手動(dòng)指定該字段的類(lèi)型為 geo_point,比如下列:

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

??mapping定義完成之后,就可以索引包含位置信息的文檔了,經(jīng)緯度信息的形式可以使字符串、數(shù)組或者對(duì)象。

PUT /attractions/restaurant/1
{
  "name":     "Chipotle Mexican Grill",
  "location": "40.715, -74.011"    // lat, lon
}
PUT /attractions/restaurant/2
{
  "name":     "Pala Pizza",
  "location": {
    "lat":     40.722,
    "lon":    -73.989
  }
}
PUT /attractions/restaurant/3
{
  "name":     "Mini Munchies Pizza",
  "location": [ -73.983, 40.719 ]    // lon, lat
}

??注意: 使用字符串進(jìn)行表示地理位置時(shí)是經(jīng)度在前,緯度在后,但是是數(shù)組表示時(shí),卻正好相反,唯獨(dú)在前,經(jīng)度在后。在es內(nèi)部,無(wú)論是什么形式,都是按照經(jīng)度在前,緯度在后進(jìn)行保存的。

2. 地理坐標(biāo)點(diǎn)過(guò)濾

??有四種地理坐標(biāo)點(diǎn)相關(guān)的過(guò)濾器可以用來(lái)選中或者排除文檔:
??(1)geo_bounding_box: 找出落在矩形框中的點(diǎn)
??該過(guò)濾器是目前為止最有效的過(guò)濾器,使用簡(jiǎn)單,只需要指定矩形的頂部,底部和左右邊界勾勒出一個(gè)矩形,就可以尋找在該矩形內(nèi)的所有文檔,使用方式如下:

GET /attractions/restaurant/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_bounding_box": {
          "location": {    // 也可以使用 bottom_left, top_right
            "top_left": {
              "lat":  40.8,
              "lon": -74.0
            },
            "bottom_right": {
              "lat":  40.7,
              "lon": -73.0
            }
          }
        }
      }
    }
  }
}

??(2)geo_distance: 找出與指定位置給定距離的點(diǎn)
??地理距離過(guò)濾器,是指定一個(gè)圓心和半徑,尋找該圓中的所有文檔。兩點(diǎn)之間的距離運(yùn)算是非常耗時(shí)的,也許我們并不需要非常精確的結(jié)果,所以我們可以指定計(jì)算距離的算法,我們可以根據(jù)需要從精度和性能之間做出權(quán)衡。
??1): arc ,最慢但是最精確。
??2): plane:這種方式是將地球看成是平面,所以這種方式相對(duì)于arc快一些,但是不是很精確。
??3):sloppy_arc:使用 Haversine formula 來(lái)計(jì)算距離。它比 arc 計(jì)算方式快 4 到 5 倍,并且距離精度達(dá) 99.9%。這也是默認(rèn)的計(jì)算方式。

GET /attractions/restaurant/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_distance": {
          "distance":      "1km",      
          "distance_type": "plane",
          "location": {
            "lat":  40.715,
            "lon": -73.988
          }
        }
      }
    }
  }
}

?? 對(duì)于distance參數(shù),訪問(wèn) Distance Units 查看所支持的距離表示單位。

??(3)geo_distance_range: 找出與指定位置給定最小距離和最大距離之間的點(diǎn)
??地理距離區(qū)間過(guò)濾器,相比于上一個(gè)過(guò)濾器的區(qū)別,就是它是一個(gè)環(huán),它會(huì)排除內(nèi)圈中的所有文檔。

GET /attractions/restaurant/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_distance_range": {
          "gte":    "1km",
          "lt":     "2km",
          "location": {
            "lat":  40.715,
            "lon": -73.988
          }
        }
      }
    }
  }
}

??(4)geo_polygon: 找出落在多邊形中的點(diǎn)

??注意:這些過(guò)濾器判斷點(diǎn)是否落在指定區(qū)域時(shí)的計(jì)算方法稍有不同,但過(guò)程類(lèi)似。指定的區(qū)域被轉(zhuǎn)換成一系列以quad/geohash為前綴的tokens,并被用來(lái)在倒排索引中搜索擁有相同tokens的文檔。由于需要做很多復(fù)雜的操作,所以地理過(guò)濾器的代價(jià)比較昂貴,在使用時(shí)應(yīng)該盡可能使用其他代價(jià)較小的過(guò)濾器比如 bool 過(guò)濾器過(guò)濾掉更多的文檔,最后再使用地理坐標(biāo)過(guò)濾器進(jìn)行篩選。

3. 按距離排序

??搜索結(jié)果可以按照距離進(jìn)行排序

GET /attractions/restaurant/_search
{
  "query": {
     "match_all": {}
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {    // 計(jì)算所有文檔按照該指定位置的距離
          "lat":  40.715,
          "lon": -73.998
        },
        "order":  "asc",
        "unit":   "km",      // 將距離以 km 為單位寫(xiě)入每個(gè)返回結(jié)果的sort鍵中
        "distance_type": "plane"
      }
    }
  ]
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 地理坐標(biāo)點(diǎn)是指地球表面可以用經(jīng)緯度描述的一個(gè)點(diǎn)。地理坐標(biāo)點(diǎn)可以用來(lái)計(jì)算兩個(gè)坐標(biāo)間的距離,還可以判斷一個(gè)坐標(biāo)是否在一...
    輕易流逝閱讀 1,473評(píng)論 0 0
  • 第3章 映射 映射是定義存儲(chǔ)和索引的文檔類(lèi)型以及字段的過(guò)程。索引中的每一個(gè)文檔都有一個(gè)類(lèi)型,每種類(lèi)型都有它自己的映...
    MR_ChanHwang閱讀 2,372評(píng)論 0 1
  • 地理坐標(biāo)點(diǎn) 可以用來(lái)計(jì)算兩個(gè)坐標(biāo)間的距離,還可以判斷一個(gè)坐標(biāo)是否在另一個(gè)區(qū)域中,或在聚合中。地理坐標(biāo)點(diǎn)不能被動(dòng)態(tài)映...
    潘大的筆記閱讀 1,022評(píng)論 0 0
  • [TOC] 一、定義 映射(mapping)即是模式定義(schema definition)。一個(gè)映射定義了字段...
    w1992wishes閱讀 5,792評(píng)論 0 1
  • - 簡(jiǎn)要介紹 我們知道es支持的數(shù)據(jù)類(lèi)型是多種多樣的,除了我們常見(jiàn)的幾種基本數(shù)據(jù)類(lèi)型,它也支持記錄位置信息的的數(shù)據(jù)...
    追殺丘比特閱讀 8,739評(píng)論 3 4

友情鏈接更多精彩內(nèi)容