我想知道人们建议在 Amazon Web Services SimpleDB 中进行空间查询的有效方法是什么?
空间查询是指在给定的纬度和经度半径内查找对象。
我想知道人们建议在 Amazon Web Services SimpleDB 中进行空间查询的有效方法是什么?
空间查询是指在给定的纬度和经度半径内查找对象。
SimpleDB 目前不提供任何内置的空间搜索操作,但这并不意味着它不能完成。有几种方法可以在非地理空间感知数据库(如 SimpleDB)中实现地理空间搜索,所有这些方法都围绕着使用数据库检索基于地理空间边界框的粗略第一选择,然后使用过滤应用程序中返回的数据的想法更精确的算法,例如Haversine 公式。
您可以lat >= minLat and lat <= maxLat and lon >= minLat and lon <= maxLat
将纬度和经度存储为(零填充和规范化)数字属性,然后执行双范围查询()。
更好的方法是使用GeoHashes。
Geohashes 提供了任意精度、附近位置的类似前缀以及逐渐从代码末尾删除字符以减小其大小(并逐渐失去精度)的可能性。
作为一个实际的例子,Geohash 6gkzwgjzn820 解码到坐标 -25.382708 和 -49.265506,而 Geohash 6gkzwgjz 将解码到 -25.383 和 -49.266,如果我们在同一区域中采取类似的位置,例如 -25.427 和 -49.315 ,我们可以看到它被编码为 6gkzmg1w(注意类似的前缀)。
来自http://geohash.org/site/tips.html
将您的项目位置作为 GeoHashes,您可以使用like
运算符搜索边界框 ( where GeoHash like '6gkzmg1w%'
),但由于like
运算符很昂贵(比较运算符),更好的方法是通过存储每个 GeoHash 前缀级别来非规范化数据(多少取决于您的所需的搜索精度)作为单独的属性(GeoHash6 GeoHash8 等),然后使用简单的等式谓词 ( where Geohash8 = '6gkzmg1w'
)。
现在谈谈 GeoHashes 的缺点。由于您无法假设 GeoHash 在您的搜索框中居中,因此您还必须搜索所有相邻前缀。geohash-js很好地描述了这个过程
Geohash 还具有随着位数减少(从右侧开始),准确性降低的特性。此属性可用于进行边界框搜索,因为彼此靠近的点将共享相似的 Geohash 前缀。
但是,由于给定点可能出现在给定 Geohash 边界框的边缘,因此有必要生成 Geohash 值列表,以便在点周围执行真正的邻近搜索。由于 Geohash 算法使用 base-32 编号系统,因此可以使用简单的查找表导出围绕任何其他给定 Geohash 值的 Geohash 值。
因此,例如,华盛顿特区宾夕法尼亚大道 1600 号解析为:38.897,-77.036
使用geohash算法,将此经纬度转换为:dqcjqcp84c6e
可以通过将此 geohash 截断为:dqcjqc 来描述围绕该点的简单边界框
但是,“dqcjqcp84c6e”不在“dqcjqc”内的中心,在“dqcjqc”内搜索可能会错过一些所需的目标。
因此,我们可以使用 Geohash 的数学特性来快速计算 'dqcjqc' 的邻居;我们发现它们是:'dqcjqf','dqcjqb','dqcjr1','dqcjq9','dqcjqd','dqcjr4','dqcjr0','dqcjq8'
这为我们提供了一个围绕“dqcjqcp84c6e”大约 2 公里 x 1.5 公里的边界框,并允许仅对 9 个键进行数据库搜索: SELECT * FROM table WHERE LEFT(geohash,6) IN ('dqcjqc', 'dqcjqf','dqcjqb' ,'dqcjr1','dqcjq9','dqcjqd','dqcjr4','dqcjr0','dqcjq8');
转换为 SimpleDB 查询,where GeoHash6 in('dqcjqc', 'dqcjqf', 'dqcjqb', 'dqcjr1', 'dqcjq9', 'dqcjqd', 'dqcjr4', 'dqcjr0', 'dqcjq8')
然后您将对结果进行 Haversine 过滤,以便仅获取搜索范围内的项目。
我将把它留在这里,因为它可能会对你有所帮助!
14 年前,我们尝试对半径范围内的位置进行地理查找表。显然没有地理空间索引或类似的东西。实际上只有标准的 SQL 和 Oracle ......无论如何,我们最终将所有 lat/lng 从固定平面场转换为公里。这些天地理空间索引基本上是做什么的。
为了解释它究竟做了什么,它把世界变成了一个平面,你甚至可以通过半径选择一些 SQL 技巧,你甚至可以得到你选择的两个点的距离。由于它也是原始的完整整数,因此查询速度非常快。
这是 PHP 中的一个简单示例,它看起来非常复杂,但一旦您理解了 SQL 查询,就很容易: