当前位置: 首页 > 知识库问答 >
问题:

在Firestore中查询Geohash

拓拔耀
2023-03-14

最近我一直在玩Geohash和FiRecovery。我的待办事项场景是收集文档(餐厅),每个餐厅都会有发送到的Geohash列表。

我想避免在文档餐厅中添加地理位置,因为文档可能比它应该的大很多倍。

最初的想法是将所有地理哈希都放在餐厅文档的子集合中,但我发现不可能在文档的子集合中执行查询。

第二个想法是将Geohash提取到交付区域集合的顶层。

document:{ restaurantName: "aRestaurant", 
deliveryArea: Arraylist<String> }

这个场景中的问题是,我将返回一个餐厅名称列表,然后我需要查询餐厅集合以获取它们,据我所知,我无法在查询中执行或操作。

这是我第一次使用文档数据库和FiRecovery。任何指导都将不胜感激。

共有2个答案

魏威
2023-03-14

我想避免在文档餐厅中添加地理位置,因为文档可能比它应该的大很多倍。

是的,不要这样做,因为文档有限制。因此,当涉及到您可以将多少数据放入文档时,会有一些限制。根据有关用法和限制的官方留档:

文档的最大大小:1 MiB(1048576字节)

如您所见,单个文档中的数据总数仅限于1 MiB。当我们谈论存储文本时,您几乎可以存储很多,但如果您使用复杂对象,这不是一个选项。

最初的想法是将所有地理哈希都放在餐厅文档的子集合中,但我发现不可能在文档的子集合中执行查询。

这是一个很好的解决方案。您的数据库结构应该如下所示:

Firestore-root
   |
   --- restaurants (collection)
        |
        --- restaurantId (document)
                |
                --- geohashes (collection)
                      |
                      --- geohashId (document)
                            |
                            --- //details about the location

因此,一个可以让你获得某个特定餐厅的所有geohash对象的查询,将非常有效。

第二个想法是将Geohash提取到交付区域集合的顶层

是一个不错的解决方案,但您应该创建一个额外的get()调用,以获取餐厅详细信息,但即使这样做,也不是一个糟糕的调用,在FiRecovery中嵌套查询没有问题。不需要OR操作。

编辑:根据您的评论,是的,您是对的,您无法查询数据库以获取餐厅对象,但我们也有一个解决方案。在这种情况下,您应该考虑通过添加如下新集合来扩充数据结构,以允许反向查找:

Firestore-root
   |
   --- geohashes (collection)
         |
         --- geohashId (document)
               |
               --- geohashRestaurants (collection)
                        |
                        --- restaurantId
                               |
                               --- //restaurant details

这项技术被称为非规范化,正如您所见,这意味着复制数据。但你需要知道,当涉及Firebase时,复制数据是没有问题的。这是一种非常常见的做法,因此,我建议您观看这段视频,Firebase数据库的非规范化是正常的。适用于Firebase实时数据库,但同样的原则也适用于云Firestore。

当您复制数据时,有一件事需要记住。就像您添加数据一样,您需要维护它。换句话说,如果您想更新/删除一个项目,您需要在它存在的每个地方都这样做。

蔡默
2023-03-14

这里是firebaser

我们最初用于Firebase实时数据库的GeoFire库通过为地理哈希设置一个单独的顶级节点准确地解决了这个问题。该节点下的每个密钥通常对应于另一个顶级节点中实际实体的密钥。

所以类似于:

locations
  key1: { g: "sa7ads", l: [ 14.5232, -156.17843 ] },
  key2: { g: "fds347", l: [ -127.172, 167.1324 ] }
restaurants
  key1: { name: "This is the first restaurant", ... },
  key2: { name: "This is the second restaurant", ... },

使用此结构,您可以对/locations执行地理查询,然后从/restaurants/$key读取每个餐厅的附加信息。这个比例相当不错。

我建议云Firestore采用同样的方法。您将拥有两个顶级集合:一个包含(较小的)位置数据,另一个包含(较大的)每个餐厅的附加数据。这会减少您读取的数据量,但最终会读取更多文档。你必须平衡这两个(带宽与文档读取)之间的关系。

几个月前,我做了一个关于在Cloud FiRecovery上执行地理查询的演讲,这可能值得一试。

 类似资料:
  • 问题内容: 我正在尝试在Firestore查询中实现逻辑OR运算符。 但这不是实现OR的正确方法。 我希望所有具有“制造商,检查者或批准者”角色的用户。 如何在Firestore查询中实施OR?Doc中没有任何内容。 问题答案: 编辑(2019年11月) 现在,CloudFirestore支持“IN”查询(公告),该查询使您可以执行一种OR查询,以查找具有相同字段中几个值之一的文档。 例如,上面的

  • 根据firestore文档,我可以通过组合'>'和'<'查询来执行相当于‘!='的查询: 但我到底该怎么做呢?如果可能,请提供精确示例的代码(查询结果!=30)。

  • Firestore文档称: 使用子句进行查询。在这种情况下,应该将查询拆分为大于查询和小于查询。例如,尽管不支持查询子句,但可以通过组合两个查询获得相同的结果集,一个查询使用子句,另一个使用子句。 我需要抓住用户在一定的年龄范围,所以这似乎是一个伟大的方式来抓住相关的,但不幸的是,我显然不明白如何使用这一点。 这不起作用,当我使用时,我会得到错误。 更新:显然他们没有专门的SWIFT文档。 我得到

  • 问题内容: 我正在使用Firebase函数和Firebase Firestore开发用于存储用户数据的API。 我想使用存储在其字段中的属性来查找文档。这是Firebase文档,其中说明了如何实现相同的功能。 我想处理两种情况 在没有文件的情况下 有两个以上具有当前条件的文件 如何处理以上两种情况? 问题答案: 按照上面的注释中的“讨论”,在Cloud Function中,您可以使用方法返回的方法

  • 我正在使用Firebase函数和Firebase FiRecovery开发一个存储用户数据的API。 我想使用存储在字段中的属性来定位文档。这是Firebase文档,其中说明了如何实现相同的目标。 我想处理两种情况 > 如果没有符合当前条件的文件 如果有两份以上的现有条件文件 上述两种情况如何处理?

  • 如何从拥有数千个文档的Firestore集合中有效地获得整个查询大小? 在我的例子中,我通过几种不同的规则查询文档: 开始日期 结束日期 位置ID 关键字 我可以使用云函数进行与前面相同的查询,但没有限制,然后得到它的大小,但有没有更有效的方法做到这一点?查询大小可能是数千个文档,那么这样做是否存在性能问题?在这种情况下,帐单是如何工作的? 如果。我的查询是1500个文档,是否需要1500个读取操