当前位置: 首页 > 知识库问答 >
问题:

Firestore:新集合与子集合

单于越
2023-03-14

我正在尝试为firestore中的社交媒体应用程序组织数据。为帖子创建一个新集合或将其放入用户的子集合更好吗?

深度应该是一样的,但是一种方式比另一种方式有什么优势吗?

创建新集合:

职位(集合)

用户(集合)

用户中的子集合:

用户(集合)

共有2个答案

龙永思
2023-03-14
  • 云Firestore中的所有查询都是经济高效的
  • 影响查询性能的唯一因素是您请求的文档数

如果您将数据从现有的实时数据库树移动到Cloud FiRecovery文档和集合,请记住数据库之间可能影响您在Cloud FiRecovery中构建数据的方式的以下主要差异:

  • 浅层查询在分层数据结构中提供了更大的灵活性
  • https://firebase.google.com/docs/firestore/firestore-for-rtdb
  • https://firebase.google.com/docs/firestore/query-data/queries#collection-group-query
  • https://www.reddit.com/r/Firebase/comments/cgq6bo/cost_and_speed_efficiency_of_root_collection_vs/
廖绍辉
2023-03-14

正如其他人所提到的,您通常应该针对读取进行优化,但“优化”的含义将取决于您的应用程序。如果你认为你很少同时从几个用户那里返回帖子,那么我想把帖子放在用户下面会更容易一些,这样你就可以快速地从一个用户那里获取所有帖子。如果你正在做一些有很多不同用户发布的常见“主题”的事情,并且你想展示关于一个主题的所有帖子,那么我想把你的所有帖子放在一个集合中要容易得多,而不是搜索多个用户集合来汇集关于一个主题的所有用户帖子。(虽然这真的不再那么困难了,因为可以在一个查询中搜索多个学院)

顺便说一句,首先要考虑的是,如果成本是一个问题,那么将一个用户的所有帖子放在一个文档中是否有意义。如果你这样做了,你可以在一个文档中读取所有的帖子,firestore的费用很大程度上是由文档读取驱动的。然而,如果你必须将来自多个用户的帖子集中在一个“主题”上,或者如果你有来自多个不同用户的帖子的“线程”,那么这种方法可能是不切实际的。

针对您的评论:让我们确保使用相同的术语。一个线程是多个不同用户在一个主题上的多篇帖子(即帖子和各种回复)。因此,如果您有一组用户,并且您对查看他们发起的所有帖子感兴趣,那么您可以保留一个ThreadPosts集合,其中包含该线程的发起人,并且线程中的每个帖子都将包含一个ThreadPost,您可以获得一个由最喜欢的用户发起的经过筛选的线程集合,然后您可以使用如下方法获取线程的帖子。

如果您想列出最喜欢的用户参与的所有线程,那么您将从最喜欢的用户那里获取所有帖子,消重线程ID列表,然后按creationTimestamp顺序拉入该threadId上的所有帖子。您可以使用fiRecovery的方法来获得这些集合,这些集合由字段值(例如“threadId”)过滤并由字段值排序(例如“creationTimestamp”)。这里有一些代码(打字稿中的AngularFiRecovery)或多或少地演示了我的意思。

 interface  ThreadPost {
   id: string;  //this is the id for this thread.
   title : string;
   originalAuthorId: string;
   creationTimestamp : number;
   lastUpdatedTimestamp: number;
 }

然后,您的posts集合也位于根目录下,可能看起来像:[Typescript]接口Post{id:string;authord:string threadId:string postest:string;creationTimestamp:number;lastUpdatedTimestamp:number;}

因此,在数据库的根目录中,有3个集合

用户发布帖子

因此,如果您想按createTimestamp顺序查看来自用户的所有帖子,您可以执行以下操作:

 async fetchPosts(userId) : Post[] {
    return getFilteredOrderedCollection("posts", "userId", ${userId}, "creationTimeStamp") 
 }

 async getFilteredOrderedCollection(collectionPath : string, filterField : string, 
                                     filterValue: string, orderByField: string) : any[] {
    let result: any[] = [];
    await AngularFirestore.collection(`${collectionPath}`).ref
      .where(`${filterField}`, "==", `${filterValue}`)
      .orderBy(orderByField).get()
      .then(function (snapshot) {
        snapshot.forEach(function (doc) {
          let p = doc.data()
          p.timestamp = Date.now();
          result.push(p)
        })
      })
      return result;
  }

如果您想要一个线程上的所有帖子,可以调用

 async fetchThreadPosts(threadId) : Post[] {
     return getFilteredOrderedCollection("posts", "threadId", ${threadId}, 
     "creationTimeStamp") 
  }

 类似资料:
  • 首先,我知道Firestore是如何工作的,并且花了很多时间评估不同的方法以获得良好的结构。但我仍在考虑以下情况: 有一个已知食谱的数据库。用户可以添加菜谱,但必须确认它们是真正的菜谱,而不仅仅是一些变体。因此,每个用户都可以从用户生成的食谱列表中选择receipes,说明他们知道如何烹饪(或添加新的)。 现在,我希望用户与其他人分享他们的receipes列表,但我不确定如何最好地使用Firest

  • 我想我读到您可以使用新的Firebase Firestore查询子集合,但我没有看到任何示例。例如,我以以下方式设置了Firestore: 舞蹈[收藏] DanceName 歌曲[收藏] 松南 我如何才能查询“查找所有的舞蹈在songName=='x'”

  • 假设我们有一个名为'Todos'的根集合。 此集合中的每个文档都有: null null

  • 如何从Flatter firestore读取子集合。我正在使用cloud\u firestore。我正在成功地将数据添加到firestore中,但无法检索它(已尝试,但失败)。我想检索名为product Firestore collection的子集合 我试过了,我没有文档ID,因为它是从fiRecovery自动生成的:

  • 在我的集合的SnapshotListener中,我使用以下命令循环遍历文档: 在 for 循环中的每个文档中,让我们称之为 ,我在 Cloud Firestore 上还有另一个文档集合。我想检索内子集合中的所有文档(每个文档只有一个字符串字段)。我能够做一个来获取本身,我用它来获取字符串字段,但我不知道如何获取其子集合中的文档。