好吧,正如其他人所提到的,您通常应该针对读取进行优化,但“优化”的含义将取决于您的应用程序。如果您认为您必须同时返回多个用户的帖子的情况很少见,那么我想将帖子放在用户下会更容易一些,因此您可以快速获取所有来自单个用户的帖子。如果您正在做一些有很多不同用户发布的常见“主题”的事情,并且您想展示他在某个主题上发布的所有帖子,那么我猜将您的所有帖子发布会容易得多在单个集合中,而不必搜索多个用户集合以将所有用户在单个主题上的帖子汇总在一起。 (尽管有了在单个查询中搜索多个集合的能力,这真的不再那么难了)
顺便说一句,需要考虑的一件事是,如果考虑成本,将用户的所有帖子放在单个文档中是否有意义。如果您这样做,您会在一个文档中读取所有帖子,并且 Firestore 费用主要由文档读取驱动。但是,如果您必须将多个用户关于“主题”的帖子汇总在一起,或者如果您的“线程”包含来自多个不同用户的帖子,则这种方法可能不切实际。
针对您的评论:让我们确保我们使用相同的术语。一个线程是来自多个不同用户的多个关于单个主题的帖子(即帖子和各种回复)。因此,如果您有一组用户,并且您有兴趣查看他们发起的所有帖子,则可以保留一个 ThreadPosts 集合,其中包含线程的发起者,并且线程中的每个帖子都包含一个 ThreadPost,您可以获得过滤收藏的用户发起的线程集合,然后您可以使用以下方法获取线程的帖子。
如果您想列出收藏夹参与的所有线程,那么您将从收藏夹用户那里获取所有帖子,删除 threadId 的重复数据列表,然后拉入该 threadId 上的所有帖子在创建时间戳顺序。您可以使用 firestore 的方法来获取这些集合,这些集合既按字段值(例如“threadId”)过滤,又按字段值(例如“creationTimestamp”)排序。这是一些代码(打字稿中的AngularFirestore)或多或少地展示了我的意思。
interface ThreadPost {
id: string; //this is the id for this thread.
title : string;
originalAuthorId: string;
creationTimestamp : number;
lastUpdatedTimestamp: number;
}
然后您的帖子 Collection 也位于根目录,可能如下所示:
[打字稿]
界面帖子{
id:字符串;
authorId : 字符串
线程ID:字符串
postTest:字符串;
创建时间戳:数字;
lastUpdatedTimestamp:数字;
}
所以在你的数据库的根目录下,你有 3 个集合:
Users Posts PostThreads
因此,如果您想按 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")
}