【问题标题】:Firestore Social Network Data Modelling for a Following System跟随系统的 Firestore 社交网络数据建模
【发布时间】:2021-10-15 02:48:11
【问题描述】:

我正在设计一个使用 java android 和 FireStore 作为后端的社交应用程序。 一开始,Firestore 建模可能是一个很大的变化,正如我所读到的,我试图让文档保持小而不是制作太多的子集合,让我们假设以下场景:

一个用户可以创建几个配置文件
个人资料有兴趣
一个用户可以关注或取消关注许多个人资料,因此一个个人资料可以被很多用户关注

用户(集合)

uid: uidUserOne
姓名:杰夫

个人资料(收藏)

idProfile:idProfileOne
名称:nameProfileOne
兴趣:{瑜伽:真,跑步:真,攀岩:真}
创建者:uidUserOne

从这里开始,我不确定如何为关注/取消关注功能建模,我想到了三个选项:

选项 A

创建一个集合,其中每个文档映射单个用户遵循一个配置文件关系

关注者(集合)

uid: uidUserOne
idProfile: idProfileOne

选项 B

一个文档映射每个配置文件的关注者,我将关注该配置文件的用户 UID 保存在一个数组中。

关注者(收藏)

idProfile:idProfileOne
追随者:{ uidUserOne: true, uidUserTwo: true, ...}

选项 C

一个文档映射每个用户的关注,我将用户关注的配置文件ID保存在一个数组中

关注者(收藏)

uid: uidUserOne
如下: { idProfileOne: true, idProfileTwo: true, ...}

我想知道哪些选项是最好的,A B r C 也可以是更好的选项...可能

我还有一个疑问,我该如何进行以下查询:
假设我是用户 One,并且我已经关注了两个对瑜伽感兴趣的个人资料,所以我想列出我尚未关注的对瑜伽感兴趣的个人资料,不知道如何完成。

【问题讨论】:

    标签: java android firebase google-cloud-firestore data-modeling


    【解决方案1】:

    据我所知,您的answer 为与Realtime Database 相关的以下系统提供了solution,而您的问题与Firestore 有关。请注意,这两个数据库都是 Firebase 的一部分,但它们都是两种不同的产品,具有两种不同的机制。

    并回答您的问题:

    选项 A. 创建一个集合,其中每个文档映射一个遵循一个个人资料关系的单个用户

    即使这个解决方案听起来有点贵,因为everything in Firestore is related to the number of reads,对于具有合理数量的用户/关注者的应用来说,它可能是一个值得考虑的解决方案。几年前我已经回答了一个类似的问题,所以请在下面查看我的答案:

    但是,想象一下阅读拥有 100 万粉丝的用户的成本?

    选项 B。一个文档映射每个配置文件的关注者,我将关注该配置文件的用户的 UID 保存在一个数组中。

    这也是一个可以继续使用的解决方案。但也要记住,文档是有限制的,所以恐怕 100 万个 UID 不适合单个文档。但是,您可以在每次达到限制时创建一个新文档。我创建了一个库,可以帮助您对照 1 MiB 的最大大小检查文档大小:

    选项C。一个文档映射每个用户的关注,我将用户关注的配置文件ID保存在一个数组中

    此选项与选项 B 相同。

    假设我是用户 One,并且我已经关注了两个对瑜伽感兴趣的个人资料,所以我想列出我尚未关注的对瑜伽感兴趣的个人资料,不知道如何完成。

    在这种情况下,“收藏”解决方案是一个可以继续使用的解决方案,因为您可以为跟随用户的每个 UID 文档添加一组兴趣。

    编辑:

    假设您有兴趣关注对瑜伽感兴趣但您不关注的用户。这是一个可以帮助您实现这一目标的架构:

    Firestore-root
      |
      --- users (collection)
      |    |
      |    --- $uid (document)
      |         |
      |         --- interests: ["yoga", "running", "climbing"]
      |
      --- followers
           |
           --- $uid (document)
                |
                --- userFollowers (sub-collection)
                      |
                      --- $followerUid (document)
                            |
                            --- //Data
    

    要获得所需的结果,您需要两个查询。一种是获取对瑜伽感兴趣的用户,另一种是仅获取您不关注的用户。实际上,您需要检查 userFollowers 子集合中不存在哪个用户。要检查用户是否不存在,请使用以下代码行:

    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    DocumentReference followerUidRef = rootRef
        .collection("followers").document(uid)
        .collection("userFollowers").document(followerUid);
    followerUidRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot document = task.getResult();
                if (!document.exists()) {
                    //Follow the user
                }
            } else {
                Log.d(TAG, "get failed with ", task.getException());
            }
        }
    });
    

    【讨论】:

    • 嗨亚历克斯!非常感谢您的回答,是的,它非常有用,我不知道“创建新文档或继续增加...”,但仍然可以弄清楚如何实现最后一个查询,您能解释一下吗进一步解决您的问题?数据建模的一个例子会很棒!
    • 您可以简单地创建一个新文档,当您达到其极限时。基本上,文档将只是一个保存数据的容器。一旦达到 1 分钟,只需创建另一个,依此类推。但不要忘记始终检查大小,否则查询会看到操作失败。关于查询,在每个对象中添加一个感兴趣的数组,并使用 whereArrayContains 方法。
    • “关于查询,在每个对象中添加一个感兴趣的数组并使用 whereArrayContains 方法” Alex 仍然没有理解您的解决方案,您指的是哪个文档?你能提供例子吗?
    • 我会在回到电脑前尝试编辑答案。
    • 抱歉我的编辑迟了。请检查我的更新答案。
    猜你喜欢
    • 2013-05-18
    • 2019-10-06
    • 2016-09-27
    • 2012-04-07
    • 2011-05-09
    • 2021-04-22
    • 1970-01-01
    • 2016-09-28
    • 2011-07-27
    相关资源
    最近更新 更多