Firestore 数据库可以对多个字段进行过滤,但只能对其中一个字段进行范围过滤。所以这个查询是可能的:
collection.where("age", ">", 18).where("age", "<", 20)
但这是不可能的:
// !!!THIS WON'T WORK!!!
collection.where("latitude", ">", 18.001).where("longitude", "<", 21.312)
据我所知,GeoFirestore 库都使用 geohashes(如原始 GeoFire 库中使用的那样)来完成一些在底层数据库上看似不可能的事情:根据纬度过滤地理范围内的文档and经度。
Geohashes 通过将位置的纬度和经度组合成单个字符串值来发挥其魔力,该字符串值可以以不同的精度进行过滤。这是可能的,因为您可以(在某种程度上)表达一个经度与一个纬度的关系。因此,您可以将纬度和经度的数字合并为一个值,该值具有每个值的最高有效数字。
现在,这也解释了为什么您不能简单地向地理查询添加另一个范围过滤器。你必须找到一种方法来用距离来表达年龄差异。如果你能做到这一点,那么“只需”将额外信息编码到地理年龄哈希中即可。对我来说这听起来很复杂,但至少是可能的。
第一个问题是,没有通用的方法将其他属性与纬度和经度相关联,这就是为什么您需要自己解决这个问题。我的直觉是,大多数开发人员放弃了这一要求,或者在客户端进行额外的排序/过滤。
如果您想向 geohash 添加相等过滤器(例如,特定地理范围内正好 18 岁的人的文档),这在 Firestore 级别上绝对是可能的,尽管我不知道 GeoFirestore 库是否公开了底层查询有能力做到这一点。
我强烈建议您更多地了解这个主题,因为它非常有趣。一些来源:
- 如果您想详细了解为什么 Firestore 只能对单个字段进行范围过滤,请观看该视频来自“了解 Cloud Firestore”系列.
- 如果您想了解更多geohashes、geoqueries 以及如何在 Firestore 上实现它们观看我关于该主题的演讲。
- 维基百科的解释是地理哈希.
我还建议您查看之前有关该主题的问题:
- 使用 Geofire + Firebase 过滤结果
- 如何使用 geofire 进行复杂查询?
- 我可以在单个查询中使用带有优先级的 firebase 的 GeoFire 吗?
其中许多都是关于(原始)Firebase 实时数据库的 GeoFire,但相同的原则也适用于 Firestore。