【问题标题】:Query for nearby locations查询附近的位置
【发布时间】:2017-09-07 13:15:57
【问题描述】:

我正在使用 Firebase 来存储用户上次扫描的纬度和经度。

条目如下所示:

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

每当用户按下特定的“搜索”按钮时,我希望我的 Firebase 功能能够获取离发送请求的人最近的人。

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

已经有 5 个用户,该功能需要大约 40 秒才能达到结果。

我也读过复合索引,但我需要以某种方式结合纬度和经度并查询这两个字段。

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

【问题讨论】:

标签: firebase firebase-realtime-database


【解决方案1】:

Firebase 数据库只能通过单个属性进行查询。所以过滤纬度和经度值的方法是将它们组合成一个属性。该组合属性必须保留您想要的数值过滤特征,例如过滤范围的能力。

虽然起初这似乎是不可能的,但实际上它是以Geohashes 的形式完成的。它的一些特点:

  1. 它是一种分层的空间数据结构,将空间细分为网格形状的桶

所以:Geohashes 将空间划分为一个桶网格,每个桶由一个字符串标识。

  1. Geohashes 提供任意精度等属性,以及逐渐从代码末尾删除字符以减小其大小(并逐渐失去精度)的可能性。

字符串越长,桶覆盖的区域越大

  1. 由于精度逐渐下降,附近的地方经常(但不总是)出现相似的前缀。共享前缀越长,两个地方越接近。

以相同字符开头的字符串彼此接近。

结合这些特征,您就会明白为什么这些 Geohashes 如此适合与 Firebase 数据库一起使用:它们将一个位置的纬度和经度组合成一个字符串,其中按字典顺序相互接近的字符串指向的位置物理上彼此接近。魔法!

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

要了解有关 Geofire 的更多信息,请查看:

【讨论】:

  • 谢谢,我会阅读并尝试这个。有没有可能,云功能超级慢?每次只查询 3 个人就需要 40 秒(不仅是第一次),而且我只访问 2 个数据库。
  • 如果您一直认为性能不合理(即使您认为 Cloud Functions 处于测试阶段),请通过minimal code that reproduces that problem 提出问题。
  • GeoFire 工作正常,但当用户的位置嵌套在用户数据中时,我无法使其工作。我的 geoFire 参考点位于“/user”,我的 geoFire 数据位于 /user/$uid/location,geoFire 会自动搜索嵌套字段还是我必须在某个地方定义“g”值所在的位置?似乎该算法正在我的“/user”条目下方而不是“位置”处寻找“g”
  • 使用 Geofire 时,您总是会得到一个单独的地理索引。该位置纯粹将位置映射到键(反之亦然)。您的实际用户数据将在数据库中的其他位置,您应该加载它,因为键进入您的查询范围并再次保留它。
  • 现在可以使用了,非常感谢。现在速度也还好,大概花了这么久,因为我没有正确实现:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 2017-06-20
  • 2019-10-30
  • 2016-03-03
  • 2016-05-02
相关资源
最近更新 更多