2017-04-11 80 views
6

我正在使用Firebase以最后一次扫描的经度和纬度存储用户。查询附近位置

的条目是这样的:

"Bdhwu37Jdmd28DmenHahd221" : { 
    "country_code" : "at", 
    "firstname" : "John", 
    "gender" : "m", 
    "lat" : 11.2549387, 
    "lon" : 17.3419559 
} 

当用户按下特定的“搜索”按钮,我希望我的火力地堡的功能,以获取人们最接近谁发送请求的人。

由于Firebase仅允许在一个字段后查询,因此我决定添加country_code,以便对该字段有一些范围限制和查询。但是,当我加载特定国家的每个用户时,它仍然超级慢,然后检查给定用户和同一个国家中的所有其他用户之间的最小距离。

已经有5个用户,该功能需要40秒才能实现结果。

我也读过关于复合索引,但我需要以某种方式结合纬度和经度和两个领域的查询。

是否有任何方法可以获得第二个和第三个查询(例如搜索相同的country_code,然后是类似的经度和纬度),还是必须在我的服务器代码中解决这个问题?

+4

https://github.com/firebase/geofire – cartant

回答

12

Firebase数据库只能通过单个属性进行查询。因此,对经度和纬度值进行过滤的方法是将它们组合成一个属性。该组合属性必须保留数字值所需的筛选特征,例如筛选范围的功能。

虽然这看起来不可能,但实际上它已经以Geohashes的形式完成。几个其性状:

  1. 它是一种分层的空间数据结构,其细分空间分隔成格子状

所以水桶:Geohashes划分空间到存储桶的网格,每个桶由一个字符串标识。

  • Geohashes提供像任意精度和逐渐从代码的末尾去除字符以减小其尺寸(和逐渐失去精度)的可能性的特性。

  • 越长串,更大的铲斗覆盖

  • 随着逐渐精度劣化的结果,附近的地方将所述区域通常(但不总是)呈现类似的前缀。共享前缀越长,两个地方越接近。

  • 字符串开始以相同字符是彼此接近的。

    结合这些特质,您可以看到为什么这些Geohashes与Firebase数据库一起使用时非常有吸引力:它们将位置的经度和纬度组合成单个字符串,其中按字典顺序彼此靠近的字符串指向位置那些物理上彼此接近。魔法!

    Firebase提供了一个名为Geofire的库,该库使用Geohashes在其实时数据库之上实现Geolocation系统。该库可用于JavaScriptJavaObjective-C/Swift

    要了解更多关于Geofire,请上网:

    +0

    谢谢,我会阅读并尝试此操作。有可能,云功能超级慢吗?每次只查询3人需要40秒(不仅是第一次),我只能访问2个数据库。 – Thomas

    +0

    如果您始终如一地表现出您认为不合理的表现(即使您认为云端函数处于测试阶段),请使用[重现此问题的最低代码]打开一个问题(http://stackoverflow.com/help/mcve) 。 –

    +0

    GeoFire工作正常,但当用户的位置嵌套在用户数据中时,我无法使其工作。我的geoFire参考点位于“/ user”,我的geoFire数据位于/ user/$ uid /位置,geoFire会自动搜索嵌套字段,还是必须在某处找到“g”值?它看起来像算法直接在我的“/用户”条目下寻找“g”,而不是“位置” – Thomas