简体   繁体   English

firestore 数据结构的最佳实践是什么?

[英]What is the best practice of firestore data structure?

I'm making a blog app using firebase.我正在使用 firebase 制作一个博客应用程序。

I want to know the best practice of data structure.我想知道数据结构的最佳实践。

As far as I know, there are 2 case.据我所知,有2种情况。 (I'm using react native) (我正在使用本机反应)

case 1:案例1:

posts
  -postID
   -title,content,author(userID),createdDate,favoriteCount

favorites
  -userID
    -favoriteList
      -postID(onlyID)
      -postID(onlyID)

In this case, for example, when we need to get favorite posts.在这种情况下,例如,当我们需要获取最喜欢的帖子时。

firebase.firestore().collection(`favorites/${userID}/favoriteList`)
    .get()
    .then((snapshot) => {
      snapshot.forEach((favorite) => {
        firebase.firestore().collection(`favorites/`).doc(`${favorite.id}`)
          .get()
          .then((post) => {
          myPostList.push(post.data())
        });
  });

in this case, we can't order the favorite posts by createdDate .在这种情况下,我们不能按createdDate对最喜欢的帖子进行createdDate So, need to sort client side.所以,需要对客户端进行排序。 Even if so, we don't use limit() function.即使是这样,我们也不使用 limit() 函数。

case 2:案例2:

posts
  -postID
  -title,content,author(userID),createdDate,favoriteCount

favorites
  -userID
     -favoriteList
       -postID
         -title,content,author(userID),createdDate,favoriteCount
       -postID
         -title,content,author(userID),createdDate,favoriteCount

firebase.firestore().collection(`favorites/${userID}/favoriteList`).orderBy('createdDate','desc').limit(30)
    .get()
    .then((snapshot) => {
      snapshot.forEach((post) => {
        myPostList.push(post.data())
      });
  });

in this case, When the favorite post is modified by the author, we have to update all of the favorite posts.在这种情况下,当作者修改了喜欢的帖子时,我们必须更新所有喜欢的帖子。 (eg If 100 users save the post as a favorite, we have to update to 100 data.) (例如,如果 100 个用户将帖子保存为收藏,我们必须更新到 100 个数据。)

(And I'm not sure we can increment favoritecount by a transaction, exactly same.) (而且我不确定我们是否可以通过交易增加favoritecount ,完全一样。)

I think if we use firebase.batch() , we can manage it.我想如果我们使用firebase.batch() ,我们可以管理它。 But I think it seems Inefficient.但我认为它似乎效率低下。

It seems that both ways are not perfect.看来这两种方式都不完美。 Do you know the best practice of this case?你知道这个案例的最佳实践吗?

What about using arrays or Collection Groups ?使用数组或集合组怎么样?

solution 1: arrays解决方案1:数组

posts
  -postID
   -title,content,author(userID),createdDate,favoriteCount
  -[favoriters(userID)]

Now you can query for a user's favorites by querying posts that "array-contains" the user's ID.现在,您可以通过查询“包含数组”用户 ID 的帖子来查询用户的收藏夹。 You can also modify individual posts without iterating through a bunch data copies.您还可以修改单个帖子,而无需遍历一堆数据副本。

There's a limit to this approach though.但是,这种方法有其局限性。 Maximum size for a document is 1 MiB;文档的最大大小为 1 MiB; assuming that a user ID is 4 bytes, a document can contain no more than 250K favoriters.假设用户 ID 为 4 个字节,则一个文档最多可以包含 250K 个收藏夹。 Clients would also have to do some O(N) processing to add / remove favoriters.客户端还必须进行一些 O(N) 处理才能添加/删除收藏夹。

solution 2: Collection Groups解决方案 2: 集合组

posts
  -postID
   -title,content,author(userID),createdDate,favoriteCount
  -favoriters {collection}
   -userID

A collection group consists of all collections with the same ID.集合组由所有具有相同 ID 的集合组成。 By default, queries retrieve results from a single collection in your database.默认情况下,查询从数据库中的单个集合中检索结果。 Use a collection group query to retrieve documents from a collection group instead of from a single collection.使用集合组查询从集合组而不是单个集合中检索文档。

So we can fetch a user's favorite posts via所以我们可以通过获取用户最喜欢的帖子

db.collectionGroup("favoriters").whereEqualTo("userID", <userID>).get();

To favorite a post, we just do要收藏帖子,我们只做

const postsRef = db.collection("posts");
postsRef.document(<postID>).collection("favoriters").add({ "userID", <userID> });

Maybe not a direct answer to your question, but the official documentation has an example for that:也许不是你问题的直接答案,但官方文档有一个例子:

Working with arrays, lists, and sets使用数组、列表和集合

Summary: Store and query data in array-like structures in documents.简介: 在文档中以类似数组的结构存储和查询数据。

Use case: If your app requires complex data objects like arrays, lists, or sets, follow the model outlined in this solution.用例:如果您的应用需要复杂的数据对象,如数组、列表或集合,请遵循此解决方案中概述的模型。 For example, in a blogging app, you might want to create a set of related posts.例如,在博客应用程序中,您可能想要创建一组相关的帖子。

https://firebase.google.com/docs/firestore/solutions/arrays https://firebase.google.com/docs/firestore/solutions/arrays

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM