在我们的应用程序中,ES 保存具有区域字段的对象,其中区域字段为 MultiPyligon 类型。(基本上,它是一个多边形数组)。
现在,我们需要搜索其中一个多边形至少部分落在给定多边形内的所有对象(在我们的例子中,它是地图的当前视口)。
我们正在试验的当前查询如下:
$params = [
'index' => self::CrimeIndex,
'body' => [
'size' => 10000,
'query' => [
'bool' => [
'filter' => [
'geo_bounding_box' => [
'areas' => [
"top_left" => [
"lat" => $neLat,
"lon" => $neLng
],
"bottom_right" => [
"lat" => $swLat,
"lon" => $swLng
]
],
]
]
]
]
],
];
问题是这个查询获取了所有接触边界框边缘的多边形。(见图)。我们如何才能获得至少部分位于边界框内的所有多边形?
映射如下:
$params = [
'index' => CrimeService::CrimeIndex,
'body' => [
"mappings" => [
'properties' => [
'areas' => [
'type' => 'geo_shape'
]
],
],
],
];
$client->indices()->create($params);
根据文档,geo_shape
可以是MultiPolygon
.
https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html
这是它看起来如何填充的示例:
GET crimes/_mapping/field/areas
提供以下内容:
更新 - 更详细的重现步骤
附上集合/索引的转储:https ://www.dropbox.com/s/8inavsvcrnuozw1/dump-2021-12-29t21_54_04.639z.json.zip?dl=0
使用 elasticsearch-php 执行的查询是:
$params = [
'index' => 'crime',
'body' => [
'size' => 10000,
'query' => [
'bool' => [
'filter' => [
'geo_bounding_box' => [
'areas' => [
"top_left" => [
"lat" => $neLat,
"lon" => $neLng
],
"bottom_right" => [
"lat" => $swLat,
"lon" => $swLng
]
],
]
],
]
]
],
];
如果我们使用参数执行它:
49.29366604017385,-123.00491857934166,49.19709977562233,-123.26617317321401
如果视口发生了一些变化,所以多边形接触到视口的边界:49.28031011582358,-122.92300503734472,49.18371770837152,-123.18425963121705
,我们得到其余的多边形: