我想知道人们建议在Amazon Web Services SimpleDB中进行空间查询的有效方法吗?
通过空间查询,我的意思是找到纬度和经度的给定半径内的物体。
答案 0 :(得分:14)
SimpleDB目前不提供任何内置的空间搜索操作,但这并不意味着无法完成。有几种在非地理空间感知数据库(如SimpleDB)中实现地理空间搜索的方法,所有这些方法都围绕着使用数据库根据地理空间边界框检索粗略的第一选择,然后使用应用程序过滤返回的数据的想法。更精确的算法,例如Haversine formula。
你可以将纬度和经度存储为(零填充和规范化)数字属性,然后执行双范围查询(lat >= minLat and lat <= maxLat and lon >= minLat and lon <= maxLat
),但由于这两个谓词都没有选择性(每个谓词都匹配很多项目)它并不理想(参见Tuning Queries)。
更好的方法是使用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
如果您的商品位置为地理位置,则可以使用like
运算符搜索边界框({{1}}),但由于where GeoHash like '6gkzmg1w%'
运算符很昂贵(Comparison Operators)更好的方法是通过存储每个GeoHash前缀级别(多少取决于您所需的搜索精度)作为单独的属性(GeoHash6 GeoHash8等)来对数据进行非规范化,然后使用简单的等式谓词(like
)。 / p>
现在是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'大约2km x 1.5km的边界框 并允许仅对9个键进行数据库搜索:SELECT * FROM table 左边(geohash,6)IN('dqcjqc', 'dqcjqf', 'dqcjqb', 'dqcjr1', 'dqcjq9', 'dqcjqd', 'dqcjr4', 'dqcjr0', 'dqcjq8');
转换为where Geohash8 = '6gkzmg1w'
的SimpleDB查询,然后您将对结果进行Haversine过滤,以便只获取搜索范围内的项目。
答案 1 :(得分:0)
我要把它留在这里,因为它可能对你有帮助!
14年前,我们尝试对半径范围内的位置进行地理查找表。显然没有地理空间索引或类似的东西。 实际上只有标准的SQL和Oracle ......无论如何,我们最终将所有lat / lng从固定平面场转换为千米。基本上是地理空间索引最近做了什么。为了解释它究竟是做什么,它将世界变成了一个平坦的表面,并且你可以通过半径来选择一些SQL技巧,你甚至可以从你选择的两个点中获得距离。由于它也是原始的完整整数,因此查询速度非常快。
这是PHP中的一个简单示例,一旦您理解了SQL查询,它就非常复杂但很容易: