Elasticsearch 计算并返回距离一共有两种方法:sort 和 script_fields
PUT /scenic_spot
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name": {
"type": "text"
},
"pin": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
},
"settings": {
"number_of_replicas": 3,
"number_of_shards": 3
}
}
PUT /scenic_spot/_doc/1
{
"id": 1,
"name": "恭王府景区",
"pin": {
"location": {
"lat": 31.007925,
"lon": 103.607572
}
}
}
PUT /scenic_spot/_doc/2
{
"id": 2,
"name": "故宫博物院",
"pin": {
"location": {
"lat": 39.917248,
"lon": 116.397176
}
}
}
PUT /scenic_spot/_doc/3
{
"id": 3,
"name": "天坛公园",
"pin": {
"location": {
"lat": 39.881265,
"lon": 116.410638
}
}
}
PUT /scenic_spot/_doc/4
{
"id": 4,
"name": "颐和园",
"pin": {
"location": {
"lat": 39.991664,
"lon": 116.271966
}
}
}
PUT /scenic_spot/_doc/5
{
"id": 5,
"name": "八达岭长城",
"pin": {
"location": {
"lat": 40.361375,
"lon": 116.019809
}
}
}
GET /scenic_spot/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_geo_distance": {
"pin.location": {
"lat": 38.912780578039346,
"lon": 120.18819440815733
},
"order": "asc",
"unit": "km"
}
}
],
"size": 1
}
响应结果如下,hits 下的 sort 字段就是距离,单位:km。
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "scenic_spot",
"_type" : "_doc",
"_id" : "3",
"_score" : null,
"_source" : {
"id" : 3,
"name" : "天坛公园",
"pin" : {
"location" : {
"lat" : 39.881265,
"lon" : 116.410638
}
}
},
"sort" : [
341.96155623680716
]
}
]
}
}
GET /scenic_spot/_search
{
"query": {
"match_all": {}
},
"_source": true,
"script_fields": {
"distance": {
"script": {
"lang": "painless",
"params": {
"lat": 38.912780578039346,
"lon": 120.18819440815733
},
"source": "doc['pin.location'].arcDistance(params.lat, params.lon)/1000"
}
}
},
"size": 1
}
5.x 以前支持:distanceInKm(lat, lon) 函数,后来被废弃。现在只支持 arcDistance(lat, lon) 函数:计算两点距离,单位为:m。响应结果如下,hits 下的 fields.distance 字段就是距离,单位:km。
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "scenic_spot",
"_type" : "_doc",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"id" : 5,
"name" : "八达岭长城",
"pin" : {
"location" : {
"lat" : 40.361375,
"lon" : 116.019809
}
}
},
"fields" : {
"distance" : [
391.55015001577397
]
}
}
]
}
}