从Firestore收集组查询中获取父母,而无需检索儿子 [英] Get parents from Firestore Collection Group Query, WITHOUT RETRIEVING SONS

查看:85
本文介绍了从Firestore收集组查询中获取父母,而无需检索儿子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个Firestore数据库,并且想知道以下架构的成本含义...

I am designing a Firestore Database and am wondering about the cost implications of the following architecture...

下面是Firestore云教程,让我们想象一下这种架构:餐厅收藏集评论子集合。像这样的东西:

Following cloud Firestore tutorials, lets imagine this architecture: A 'Restaurants' Collection has a 'Reviews' subcollection. Something like:

--Restuarants
   --My Restaurant
      --Reviews
         --My Review 1, through n

我有兴趣查询评论子集合,我并不真正感兴趣

I am interested in querying the reviews subcollection, but I am not really interested in the review itself, but on the restaurants.

例如,在类似的查询中,获取所有发布于2019年8月1日的评论我实际上对在2019年8月1日发布至少评论的餐厅感兴趣。即。 我想找回餐厅的文件,而不是评论

So, for instance, in a query like Get all reviews posted on August 1st 2019 I am actually interested in the restaurants that have at least one review posted on August 1st 2019. ie. I would like to get back the restaurants' documents, not the reviews.

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

From this post and this it seems like my implementation would probably look something like this:

    QuerySnapshot myQuerySnapshot = await Firestore.instance.collectionGroup('reviews')
                .where('reviewDate', isEqualTo: '20190801').snapshots().first;
    List<DocumentSnapshot> myDocumentSnapshots = myQuerySnapshot.documents;

    myDocumentSnapshots.asMap().forEach((index, son) {
          snapshot.reference.parent().parent().get().then((parent) {
            print("Printing snapshot: $index");
            print("son id: "+son.documentID);
            print("parent id: "+parent.documentID); //I could then retrieve the parent data.
            });
    });

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

With this implementation, I would be fetching all the 'sons' (ie. all the reviews). This has a couple of disadvantages:


  • 成本。一家餐厅可能在2019年8月1日发布了1000条评论;我将被收取1001次读取费用(1000条评论+我感兴趣的实际父文档)。

  • 数据消耗。我的用户会从服务器中检索比实际需要更多的数据。

  • Cost. A restaurant may have, say, 1000 reviews posted on august 1st 2019; I would be charged for 1001 reads (1000 reviews + the actual parent document I am interested in).
  • Data consumption. My users would retrieve way more data from the servers than what is actually needed.

有没有更好的方法?有没有一种方法可以避免获取评论并仅获取父文档?

Is there a better way to do this? Is there a way to avoid fetching the reviews and getting only the parent documents?

谢谢!

推荐答案

在查询评论集合时,无法找回餐厅。因此,您要做的就是在不更改数据模型的情况下获取餐厅的唯一方法。

There is no way to get back restaurants when you're querying the reviews collection(s). So what you're doing is the only way to get the restaurants without changing your data model.

像往常一样,在处理NoSQL数据库时,将数据模型修改为更好的方法可能更好。适合此用例。我能想到的快速替代方法是在饭店文档中保留一个数组 datesWithReviews ,每当您向 reviews添加评论时,都会更新该数组该餐厅的子集合。如果您使用 array-union 操作更新数组,则只要为日期添加评论,就可以更新餐厅,而数组中没有重复的日期。

As usual when dealing with NoSQL databases, it may be better to modify your data model to better suit this use-case. The quick alternative I can think of is to keep an array datesWithReviews in the restaurant document, which you update whenever you add a review to the reviews subcollection of that restaurant. If you use an array-union operation to update the array, you can update the restaurant whenever a review is added for a date, without having duplicate dates in the array.

使用每个餐厅文档中的该字段,然后可以查询包含该日期的所有餐厅。如果将日期存储为简单的 2020-07-19 字符串,该查询将类似于:

With that field in each restaurant document, you can then query across all restaurants that contain that date. If you store the dates as simple "2020-07-19" strings, that query would look like:

firebase.firestore().collection("restaurants").where("reviewDates", "array-contains", "2020-07-19")

这类似于在在交易中写入数据。另请参见该步骤的视频演练。

This is similar to how restaurant ratings are updated when a review is added in the FriendlyEats codelab step on writing data in a transaction. Also see the video walkthrough of that step.

这篇关于从Firestore收集组查询中获取父母,而无需检索儿子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆