首页 > 解决方案 > 您将如何在 Firestore 上构建互评社交网络模型?

问题描述

我认为用一个例子来展示我的模型会更容易。该应用程序的功能如下:它将是社交网络模式。共同的朋友模型。当用户登录应用程序时,将显示一个列表。每个列表项都包含一个朋友name- photos(photo1, photo2) -rating对于每张照片(根据两个评分计算)。

示例:
以 UserA 身份登录:

list item1:
[
 name: UserBName,
 photo1: 5 (UserA rated it 2, UserB rated it 8),
 photo2: 4 (UserA rated it 3, UserB rated it 5)
],
list item2:
[
 name: UserCName, 
 photo1: 2 (UserA rated it 1, UserC rated it 4)
]

我正在考虑为每个用户文档创建一个朋友子集合,并且内部具有这样的结构:

UserB: {
     name: UserBName,
     photo1:{
      rating from UserA: 4
      rating from UserB: 2
     },
     photo2:{
      rating from UserA: 3
      rating from UserB: 5
     }
    }

我的问题是 UserB(document)->friends(subcollection)->UserA(document) 会有相同的数据,我不确定它是否是一个可行的解决方案。

标签: androidfirebasegoogle-cloud-firestorenosql

解决方案


复制数据和非规范化数据是 NoSQL 数据库中的常见做法。它用于展平结构,以便可以对数据运行查询。在这个问题中,我们不知道您想要运行什么样的查询,除了

当用户登录应用程序时,将显示一个列表。每个列表项都包含一个朋友姓名 - 照片(照片 1,照片 2) - 每张照片的评分(根据两个评分计算)。

这不需要查询。使用问题中的结构,当 UserB 登录时,您的应用程序将读取 UserB 文档,该文档将包含他们的姓名以及他们的所有照片和评级,因此所有这些数据将在文档被读取后立即可用。

然而...

如果每个用户都有很多照片,那么可能需要读取大量数据,并且可能会使设备不堪重负。此外,如果您真的想避免重复数据,那么您需要将数据放在一个地方。

我会完全改变结构,以提供更大的灵活性,只读取你想要的数据。

首先是一个更简单的用户集合:documentId 是用户 uid,然后将他们的姓名等存储为每个文档中的字段

users
   uid_0:
      name:
   uid_1:
      name:

然后是一个存储评分的照片集

firestore_root
   photos
      photo_0
         uid_0: 4
         uid_1: 2
      photo_1
         uid_3: 2
         uid_2: 5
      photo_2
         uid_0: 3
         uid_1: 1

因此,当用户登录时,在照片的节点上对所有包含用户 uid 且评分 > -1 的照片执行查询(例如,假设评分从 0 到 5)。在这种情况下,那将是 photo_0 和 photo_2

在伪代码中,获取 uid_1 已评级的所有节点

queryPhotos() {
    photoCollection.whereField("uid_1", isGreaterThan: -1).getDocuments() { querySnapshot, error in
        //the snapshot will contain photo_0 and photo_2
        for doc in querySnapshot.documents { //iterate over each photo
            //you'll have all of the fields here and can calculate an average rating
            print(doc.documentID, doc.data())
        }
    }
}

推荐阅读