Firebase 有效地模拟 nXn 关系

Firebase efficiently model nXn relationship

假设我有以下场景:

我有多个活动,多个用户可以参加。此外,用户可以参加多个活动。存储所需信息并保持数据一致性的最佳方式是什么?

这是我的想法以及我不太喜欢它们的原因:

collection "events" -> event document -> subcollection "users" -> user document 问题: 每个用户都存在于每个事件上,从而导致每个用户有多个文档。我不能只更新用户信息,因为我需要写入每个相关事件文档并获取相关用户文档。 如果试图尽可能减少 reads/writes ,那真是一场灾难 例如:

this.afs.collection('events').get().then(res => {
    res.forEach(document => {
        document.ref.collection('users', ref => ref.where('name', '==', 'Will Smith')).get()
        //Change name accordingly
    })
})

collection "users" -> user document -> subcollection "events" -> event document 问题: 每个事件都存在于每个用户上,导致每个事件的多个文档。 (与第一种情况相同的问题,只是反过来)

collection "users" and collection "events" 每个都有用户和事件作为从属于它们的文档。 有一个数组 attending_events,其中包含相关的事件 ID。 问题: 有点像 SQL 的排序方式。需要使用 forEach() 函数通过单独的查询获取每个文档。 例如

this.afs.collection('events').doc(eventId).get().then(res => {
    res.users.forEach(elem => {
        this.afs.collection('users').doc(elem.name).get()
        //Change name accordingly
    })
})

我错过了什么,是否有更好的方法来模拟所需的架构?

When using collection "events" -> event document -> subcollection "users" -> user document

并没有您想的那么糟糕。这种做法称为 denormalization 并且是 Firebase 的常见做法。如果您是 NoSQL 数据库的新手,我建议您观看此视频 Denormalization is normal with the Firebase Database 以便更好地理解。它适用于 Firebase 实时数据库,但同样的规则适用于 Cloud Firestore。

I want to be able to change user information or event information without the need of fetching hundreds of documents.

如果您认为用户详细信息会经常更改,那么您应该考虑在每个 user 对象下存储一个 array 的事件 ID,而不是 使用子集合。同样,你也应该在每个 event 对象下添加一个 array 的 UID。您的新架构应如下所示:

Firestore-root
   |
   --- users (collection)
   |    |
   |    --- uid (document)
   |         |
   |         --- events: ["evenIdOne", "evenIdTwo", "evenIdThere"]
   |         |
   |         --- //Other user properties
   |
   --- events (collection)
        |
        --- eventId (document)
             |
             --- users: ["uidOne", "euidTwo", "uidThere"]
             |
             --- //Other event properties

由于您只持有引用,因此当用户名更改时,无需在 events 子集合中存在的所有用户对象中更新它。但是请记住,在这种方法中,例如要获取用户分开的所有事件,您应该创建两个查询,一个是从用户文档中获取事件 ID,第二个是根据这些事件 ID 获取事件文档。

基本上这是在使用非规范化和将数据存储在数组之间的权衡。

What's the best way of storing the required information with maintaining data consistency?

通常,我们根据要执行的查询创建数据库模式。有关更多信息,我还建议从以下 post:

中查看我的答案