Firestore聊天应用程序:这是一个适用于多收件人邮件的有效文档结构吗



假设一个聊天应用程序有1000万Firebase用户和数亿条消息。

我有一个Firestore集合,其中包含以时间序列中的文档表示的消息,其中每个消息最多可以被100个用户接收和查看。请注意,这些用户没有被组织在稳定的组中,因为每条消息可能有一组完全不同的用户接收它

我需要能够非常有效地(在时间和成本方面)找到,在某个特定时间之后的所有消息,指向某个特定用户。

我的第一次失败尝试是在recipients数组字段中列出收件人用户,例如:

sender: user3567381
dateTime : 2019-01-24T20:37:28Z
recipients : [user1033029, user9273842, user8293413, user6273581]

然而,这将不允许我高效地进行查询。

作为第二次失败的尝试,由于Firestore是无计划的,我考虑让每个用户都有一个字段,如下所示:

sender: user3567381
dateTime : 2019-01-24T20:37:28Z
user1033029 : true
user9273842 : true
user8293413 : true
user6273581 : true

例如,如果我想知道今天下午3点之后用户8293413的所有消息,我可以这样做:

messages.where("user8293413", "==", true).where("dateTime", ">=", "2019-01-24T15:00:00Z")

这是一个复合索引查询,每个用户需要一个索引。不幸的是,每个数据库有200个复合索引的限制。

为了解决这个问题,我的当前尝试是将日期转换为用户字段的值,如下所示:

sender: user3567381
dateTime : 2019-01-24T20:37:28Z
user1033029 : 2019-01-24T20:37:28Z
user9273842 : 2019-01-24T20:37:28Z
user8293413 : 2019-01-24T20:37:28Z
user6273581 : 2019-01-24T20:37:28Z

现在,如果我想知道今天下午3点之后用户8293413的所有消息,我可以这样做:

messages.where("user8293413", ">=", "2019-01-24T15:00:00Z")

请注意,这现在是单个字段索引

从文档中我知道Firestore将为所有字段创建单个字段索引,因此这意味着它将为user8293413创建特定的索引。这意味着搜索会很快,对吧?并且读取次数将保持在最低限度(每条消息读取一次)。

但是,由于我有1000万用户,Firestore将不得不为整个数据库创建1000万个单字段索引(假设所有用户都收到消息)。

从文件来看,Firestore有以下限制:

  • 数据库的最大复合索引数:200
  • 数据库的单个字段索引豁免的最大数目:200
  • 每个文档的最大索引条目数:40000(索引条目数是文档的以下各项之和:单个字段索引条目数+复合索引条目数)
  • 索引项的最大大小:7.5 KiB
  • 文档索引项大小的最大总和:8 MiB(文档的总大小是以下各项的总和:文档的单个字段索引项大小之和+文档的组合索引项大小总和)
  • 索引字段值的最大大小:1500字节(超过1500字节的字段值将被截断。涉及截断字段值的查询可能返回不一致的结果。)

通过阅读以上内容,这些内容引起了我的注意:

  • 每个文档的最大索引条目数:40000
  • 文档索引项大小的最大总和:8 MiB

但是,他们指出限制是针对每个文档的,而不是针对每个数据库的。我只有数百万个数据库索引,而不是每个文档的索引。

这是个问题吗?那么多索引会影响性能吗?所有这些索引的存储成本如何?Firebase是否为每个数据库的大量索引总数做好了准备?

尽管几个月后,对于任何未来的用户来说,第一次尝试似乎效果最好。

使用单个静态字段作为时间戳,使用单个静态域作为收件人,这意味着索引可以忽略不计,您不必考虑它们。

查找用户的所有消息,这似乎是你的目标:

例如,如果我想知道用户8293413在今天下午3点,我可以这样做:

这在伪代码:中看起来就像这样

firestore.collection('messages').where('recipient', 'array_contains', userId).where('time', '>', '3pm today'.get()

这在性能上应该很容易,Firebase针对其提供的运算符进行了优化,例如"=="、">="、"array_contents">

相关内容

最新更新