从 Firestore Collection Group 查询中获取父母,而不检索儿子

And*_*lva 6 database-design firebase google-cloud-firestore

我正在设计一个 Firestore 数据库,想知道以下架构的成本影响......

按照云 Firestore 教程,让我们想象一下这种架构:“餐厅”集合有一个“评论”子集合。就像是:

--Restuarants
   --My Restaurant
      --Reviews
         --My Review 1, through n
Run Code Online (Sandbox Code Playgroud)

我有兴趣查询评论子集合,但是我对评论本身并不真正感兴趣,而是对餐厅感兴趣。

举例来说,在这样的查询中,我实际上对2019 年 8 月 1 日至少发布了一篇评论餐厅Get all reviews posted on August 1st 2019感兴趣。IE。我想拿回餐厅的文件,而不是评论

这篇文章这篇文章来看,我的实现可能看起来像这样:

--Restuarants
   --My Restaurant
      --Reviews
         --My Review 1, through n
Run Code Online (Sandbox Code Playgroud)

通过这个实现,我将获取所有“儿子”(即所有评论)。这有几个缺点:

  • 成本。例如,一家餐厅可能在 2019 年 8 月 1 日发布了 1000 条评论;我将按 1001 次阅读付费(1000 条评论 + 我感兴趣的实际父文档)。
  • 数据消耗。我的用户将从服务器检索的数据比实际需要的数据多得多。

有一个更好的方法吗?有没有办法避免获取评论并仅获取父文档?

谢谢!

Fra*_*len 3

当您查询评论集合时,无法返回餐厅。因此,您正在做的事情是在不更改数据模型的情况下获得餐厅的唯一方法。

与往常一样,在处理 NoSQL 数据库时,最好修改数据模型以更好地适应此用例。我能想到的快速替代方案是在餐厅文档中保留一个数组datesWithReviews,每当您向该reviews餐厅的子集合添加评论时都会更新该数组。如果您使用array-union操作来更新数组,则每当为某个日期添加评论时,您都可以更新餐厅,而数组中不会出现重复的日期。

通过每个餐厅文档中的该字段,您可以查询包含该日期的所有餐厅。如果将日期存储为简单"2020-07-19"字符串,则该查询将如下所示:

firebase.firestore().collection("restaurants").where("reviewDates", "array-contains", "2020-07-19")
Run Code Online (Sandbox Code Playgroud)

这类似于在FriendlyEats Codelab 中在事务中写入数据的步骤中添加评论时餐厅评级的更新方式。另请参阅该步骤的视频演练。