【问题标题】:Using "array-contains" Query for Cloud Firestore Social Media Structure对 Cloud Firestore 社交媒体结构使用“array-contains”查询
【发布时间】:2019-04-20 05:20:52
【问题描述】:

我有一个由集合组成的数据结构,称为“投票”。 “民意调查”有几个随机生成 ID 的文档。在这些文档中,还有一个称为“答案”的附加集合集。用户对这些投票进行投票,投票全部写入“答案”子集合。我在“answers”节点上使用 .runTransaction() 方法,其想法是这个子集合(对于任何给定的民意调查)会不断被用户更新和写入。

我一直在阅读有关social media structure for Firestore 的信息。不过,我最近遇到了 Firestore 的一项新功能,即“array_contains”查询选项。

虽然上面的帖子引用讨论了社交媒体结构的“关注”提要,但我有一个不同的想法。我设想用户向我的主要投票节点写入(投票),因此创建另一个“跟随”节点并让用户写入该节点以更新投票计数(使用云功能)似乎非常低效,因为我必须不断地复制来自正在统计选票的主节点。

“array_contains”查询是否会成为社交媒体结构可扩展性的另一个实用选项?我的想法是:

  1. 如果用户 A 关注用户 B,则写入我的“用户”节点中名为“关注者”的直接数组子节点。
  2. 在用户 B 创建任何投票之前,用户 B 的设备会从 Firestore 中读取“关注者”数组,以获取关注的所有用户的列表,并将其填充到客户端的 Array 对象中
  3. 然后,当用户 B 编写新的投票时,将该“关注者”数组添加到投票中,这样用户 B 的每个新投票都会附加一个数组,其中包含关注用户的所有 ID。

“array_contains”查询有哪些限制?在 Firebase 中存储一个包含数千个用户/关注者的数组是否可行?

【问题讨论】:

  • 请标记相关技术。虽然您可能使用的是 Android/Java,但您共享的代码和您的问题似乎纯粹是关于 JavaScript/Node.js。另外:你的问题是什么?
  • 您的描述是关于 Cloud Firestore,但您的代码混合了 Cloud Firestore 和实时数据库(它们是完全独立的服务)。通常,在 DB 中建模单边追随者模型的成本很高。您很可能希望/需要对数据进行非规范化处理,以便将新的民意调查(或至少他们的 ID)写入每个关注者的集合中。
  • 因此,您想的不是“关注者”,而是有一个用户节点,然后在其下方有一个集合“关注者?”

标签: java android firebase


【解决方案1】:

“array_contains”查询是否会成为社交媒体结构可扩展性的另一个实用选项?

当然可以。这就是 Firebase 创建者添加此功能的原因。

看到你的结构,我想你可以试一试,但要回答你的问题。

“array_contains”查询有哪些限制?

对于您存储的数据类型没有限制。

在 Firebase 中存储一个包含数千个用户/关注者的数组是否可行?

与实用与否无关,与其他类型的限制有关。问题是文档有限制。因此,在您可以将多少数据放入文档时存在一些限制。根据usage and limits的官方文档:

文档的最大大小:1 MiB(1,048,576 字节)

如您所见,单个文档中的数据总量限制为 1 MiB。当我们谈论存储文本时,您可以存储很多东西。因此,在您的情况下,如果您只存储 ID,我认为这不会有问题。但是恕我直言,随着您的数组越来越大,请注意这个限制。

如果您在数组中存储大量数据并且这些数组应该由大量用户更新,那么您需要注意另一个限制。因此,每个文档每秒只能写入 1 次。因此,如果您遇到很多用户都试图一次将数据写入/更新到相同文档的情况,您可能会开始看到其中一些写入失败。所以,也要小心这个限制。

【讨论】:

  • 非常感谢您的及时回复。您知道 Firestore 是否对这些限制发表了评论 - 它们是否可能会增加?另外,如果有 1 MB 的空间,可以说它包含 1,000,000 个文本字符吗?
  • 我真的不知道他们将来是否会增加这些限制。你应该问他们。因此,大约 1000 个字符等于 1 KB。你可以做数学:)
  • 另外,firestore 文档有 40,000 个索引字段的限制。这意味着如果您有一个包含 40,0010 个字段的文档(数组和映射中的每个元素都被视为索引字段)最后 10 个字段将不会被索引,因此您将永远无法查询这些数据。参考:youtube.com/watch?v=lW7DWV2jST0
  • 这里添加更多限制是文档中最多可以有 20k 行。这意味着可以添加一个大小为 19999 的数组,其中将采用 1 行,按数组名称使其总计 20k。现在超过此限制,您无法在文档中添加任何其他字段。解决方案:在这种数组情况下,将您的数据存储在子集合中。
【解决方案2】:

我做了一个实时投票系统,这是我的实现:

我创建了一个 polls 集合,其中每个文档都有一个唯一标识符、一个标题和一组答案。

此外,每个文档都有一个名为 answers 的子集合,其中每个答案都有一个标题以及它们自己的 shards 子集合中的分布式计数器总数。

例子:

polls/
  [pollID]
    - title: 'Some poll'
    - answers: ['yolo' ...]
    answers/
      [answerID]
        - title: 'yolo'
        - num_shards: 2
        shards/
          [1]
            - count: 2
          [2]
            - count: 16

我创建了另一个名为 votes 的集合,其中每个文档都是 userId_pollId 的复合键,因此我可以继续跟踪用户是否已经投票。 每个文档都包含 pollId、userId、answerId...

创建文档时,我会触发一个云函数来获取 pollId 和 answerId,并使用事务在此 answerId 的分片子集合中增加一个随机分片计数器。

最后,在客户端,我减少投票的每个答案的每个分片的计数值来计算总数。

对于以下内容,您可以使用名为“following”的中间人集合来执行相同的操作,其中每个文档都是 userAid_userBid 的复合键,因此您可以轻松跟踪哪个用户正在关注另一个用户没有打破 Firestore 的限制。

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 2020-01-22
    • 2021-02-12
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多