我的要求是检查特定的geoPoint是否落在圆半径内。我正在使用geoShape:circle来存储位置。我的文档如下:
PUT location_test/doc/1
{
"location" : {
"type" : "circle",
"coordinates" : [73.7769,18.5642],
"radius": "10mi"
}
}
并且查询如下:
GET location_test/_search
{
"query": {
"bool": {
"must": [
{
"geo_shape": {
"location": {
"shape": {
"type": "point",
"coordinates": [
73.877097,
18.455303
],
"relation": "contains"
}
}
}
}
]
}
}
}
此查询非常适合单圆几何形状。但是,现在我要检查特定的geoPoint是否落在多个圆的半径内。我们可以给我们类似的文档吗:
{
"location": [
{
"type": "circle",
"coordinates": [
73.7769,
18.5642
],
"radius": "10mi"
},
{
"type": "circle",
"coordinates": [
-118.240853,
34.052997
],
"radius": "10mi"
}
]
}
并进行查询以检查geoPoint是否落在哪个圆中。还是有其他方法可以实现这一目标?
编辑使用地理位置数组对特定地理位置的文档进行排序是否是一种好习惯?
Mapping :
{
"mappings": {
"doc": {
"properties": {
"locationPoint": {
"type": "geo_point"
}
}
}
}
}
PUT location_test2/doc/1
{
"locationPoint": ["34.075433, -118.307228","36.336356,-119.304597"]
}
PUT location_test2/doc/2
{
"locationPoint": ["34.075433, -118.307228"]
}
GET location_test2/_search
{
"sort": [
{
"_geo_distance": {
"locationPoint": "34.075433, -118.307228",
"order": "asc"
}
}
]
}
您当然可以在一个文档中有多个圆圈,并且如果圆圈中的[[any包含您的观点,搜索仍将匹配。为简洁起见,折叠步骤:
PUT location_test
{"mappings":{"properties":{"location":{"type":"geo_shape","strategy":"recursive"}}}}
加入您的圈子列表:
PUT location_test/_doc/2 {"location":[{"type":"circle","coordinates":[73.7769,18.5642],"radius":"10mi"},{"type":"circle","coordinates":[-118.240853,34.052997],"radius":"10mi"}]}
与单个圆圈的查询相同。
GET location_test/_search {"query":{"bool":{"must":[{"geo_shape":{"location":{"shape":{"type":"point","coordinates":[73.7769,18.5642],"relation":"contains"}}}}]}}}
这将产生我们感兴趣的文档。违反直觉但很好的一点是,如果提供单个对象或对象列表,则无所谓。 ElasticSearch无需更改映射即可处理两者。
请注意,您的circles位于地球的相对侧:如果您知道这一点,并且查询
locations
就是这样,那么一切都很好。
从性能的角度记住,圆被表示为多边形,这取决于您的ES版本,表示为一堆triangles。
因此,您可能希望为类似圆形的多边形而不是为圆形索引,以加快索引编制速度,甚至考虑将您的圆形合并到一组多边形(MultiPolygon)中,因为从外观上看,您的圆形列表代表相关几何。