Firestore DB 设计在 N 次读取/天后排除文档

Firestore DB design to exclude a document after N reads / day

我正在尝试使用 Firebase Firestore 制作一个约会应用程序,有点类似于 Tinder。
我想优化解决一个有趣的数据库设计问题。

关于

每天,我的个人资料都会显示给当天登录的有限数量的人(比如 100 人)。现在让我们忘记距离和其他匹配因素,只考虑每天向 100 个新的随机人显示我的个人资料。

问题

实现此功能需要什么样的 Firestore 数据库设计?
我确实知道如何解决这个问题(见下文),但它有很多缺点。
你能提出更好的主意吗?

我目前的解决方案 :

我维护一个 firestore 集合,其中每个配置文件都是其中的一个文档。每个个人资料文档都维护一个 todaysReadCount 字段,用于跟踪个人资料今天被阅读的次数。

然后使用此查询为每个用户获取 50 个配置文件:

firestore.collection("Profiles").where('todaysReadCount','<=', 100).limit(50).get();

抓取完成后,客户端(应用程序)将立即更新所有这 50 个个人资料文档 todaysReadCount + 1

foreach uid_i in fetched50profiles {
  firestore.collection("Profiles").doc(uid_i).update({
    todaysReadCount: FieldValue.increment(1)
  });
}

每个午夜,云函数都会在所有配置文件中重置此计数器。

理论上这应该可行,但这种方法存在多个问题:

  1. 为了维护计数器,会有很多写入。至少 100 次写入/配置文件/天。这将增加我的 firestore 账单 $$$。

  2. 在午夜更新所有配置文件文档,也是一个巨大的开销,将花费 $$$。

  3. 由于读取配置文件和更新他们的计数器不是一个单一的事务,因此读取和更新之间会有延迟。如果大量人员同时登录,这可能会导致配置文件读取次数超过 100。 (但我想这不是什么大问题)

你能提出更好的解决方案吗?

减少每晚清理需要的一件事是按日期存储计数器,而不仅仅是今天。所以为每一天添加一个字段:

readCount_20200413: 100,
readCount_20200414: 42,
readCount_20200415: 1

虽然您仍然需要定期清理这些计数器以防止 运行 超过最大文档大小或索引数量,但您可以以更短的间隔执行此操作,从而减少每晚的数量写。

您将需要 pre-seed 将即将到来的日期计数设为 0,否则如果日期没有计数,查询将不会 return 文档。


另一个改进是将计数器存储在一个更好地满足您的计费要求的系统中,Dharmaraj 将其评论为缓存。例如,您可以将计数器保存在 Firebase 实时数据库中,这通常会便宜得多 use-case。

然后您可以查询这个备用数据源,或者您可以在每次写入时检查新计数器值是否超过您的阈值,并在 Firestore 中更新配置文件以将其从那里的查询中排除。

所以你最终会在实时数据库中得到计数器,在 Firestore 中得到更简单的布尔字段,这也意味着你在那里不需要范围查询。

canShowOn_20200413: false,
canShowOn_20200414: true,
canShowOn_20200415: true
canShowOn_20200416: true
canShowOn_20200417: true