我正在开发一个应用程序,用户将根据其位置接收基于地理位置的信息。服务器应该能够处理大量连接的客户端> 100k。
现在我想出了关于如何处理用户位置的4种方法。
方法 - 没有地理空间索引:
应用服务器只会保存已连接客户端的列表,并且他们会定位。 只要有可用的信息,服务器就会遍历整个列表并检查客户端是否在给定的半径范围内。
怀疑:非常昂贵
方法 - 处理应用服务器中的地理空间索引:
应用服务器确实维护了一个R树,其中包含所有连接的客户端以及它们的位置。 因此我看着JSI Java Spatial Index
怀疑:使用JSI更新地理空间索引非常昂贵
方法 - 让数据库" mongoDb"做地理空间索引/计算:
app服务器仅保存对连接的客户端(连接)的引用,并将该引用的密钥及其位置保存到mondoDb中。 当有新信息可用时,服务器可以查询数据库以获取附近所有客户端的密钥。
Pro :我想mongoDb确实比我在应用服务器上做的更好地实现了地理空间索引。
怀疑:客户四处旅行迫使我经常更新地理空间索引。我可以这样做,还是我遇到性能问题?
方法 - 拥有"指数"使用二维数组
今天我在考虑使用二维数组创建一个非常简单的索引。虽然外部阵列是经度,但内部是纬度。 让我们说3经度/海拔度就足够了。 我可以通过
收到给定区域的用户列表ArrayList userList = data [91] [35] //91.2548980712891,35.60869979858; //我还需要让周围阵列中的用户90; 35,92; 35 ...... //如果我需要更多的精度,我可以再使用一个十进制数据[912] [356]
Pro :无需查询数据库即可快速读写访问
怀疑:极点处的半径更短。丑陋的黑客?
如果有人能指出我进入""我将非常感激。正确的方向。
答案 0 :(得分:0)
MongoDB用于地理空间索引的索引基于geohash,它实际上将2维空间转换为适合B树索引的一维密钥。虽然这比R-tree索引的效率稍低,但它比方案1效率更高。我还认为使用空间查询过滤数据库级别的数据将比创建您更有效,更易于维护自己的空间索引策略。
使用MongoDB需要注意的主要事项是,不能使用几何列作为分片键,但可以使用另一个键对包含几何字段的集合进行分片。此外,如果您希望进行任何聚合查询(从您的问题中无法清除),几何字段必须是管道中的第一个。
还有一个geohaystack索引,它基于小型存储区并针对基于小区域的搜索进行了优化,请参阅http://docs.mongodb.org/manual/core/geohaystack/,这可能对您的情况有用。
就速度而言,B-Tree索引上的插入和搜索基本上是O(log n),请参阅Wikipedia B-Tree,而没有索引则搜索将是O(n),因此它不会需要很长时间才能在有和没有索引之间表现差异很大。
如果您担心重写会减慢速度,您可以调整write concern in MongoDB,这样您就不必等待大多数副本响应每次写入(默认),但是如果您丢失主人,则以可能不一致的数据为代价。