最近,我将数据模型从Firebase移动到了Firestore.我所有的代码都正常工作,但在检索某些数据的嵌套查询方面,我遇到了一些麻烦.重点是:

现在,我的此部件的数据模型如下所示(是!另一个关注者/订阅源示例):

{
  "Users": { //Collection
    "UserId1" : { //Document
      "Feed" : { //Subcollection of Id of posts from users this user Follow
        "PostId1" : { //Document
          "timeStamp" : "SomeDate"
        },
        "PostId2" : {
          "timeStamp" : "SomeDate"
        },
        "PostId3" : {
          "timeStamp" : "SomeDate"
        }
      }
      //Some data
    }
  },
  "Posts":{ //Collection
    "PostId1":{ //Document
      "Comments" :{ //Subcollection
        "commentId" : { //Document
          "authorId": "UserId1"
          //comentsData
        }
      },
      "Likes" : { //Subcollection
        "UserId1" : { //Document
          "liked" : true
        }       
      }
    }
  }
}

我的问题是,为了检索用户提要的帖子,我应该用下一种方式进行查询:

  • 从我的订阅源获取按时间戳排序的最后X个文档

feedCol(userId).orderBy(CREATION_DATE, Query.Direction.DESCENDING).limit(limit)

  • 之后,我应该对从列表中检索到的每个帖子执行一次查询:workoutPostCol.document(postId)

  • 现在我有了每篇帖子的数据,但我想拍下用户名、图片和点数..等作者,这是在一个不同的Document,所以,再次,我应该做另一个单一的查询,每authorId检索到的帖子列表userSocial(userId).document(toId)

  • 最后,同样重要的是,我需要知道我的当前用户是否已经喜欢该帖子,因此我需要(再次)对每个帖子执行一次查询,并判断我的userid是否在posts/likes/{userId}以内

现在一切正常,但考虑到Firestore的价格取决于数据库调用的数量,而且这并没有使我的查询变得更简单,我不知道是我的数据模型不适合这种数据库,我应该转到正常的SQL还是再回到Firebase.

Note:我知道,将喜欢、提要等子集合移动到我的用户或post文档中的ArrayList中,一切都会容易得多,但文档的限制是1MB,如果增长太多,它将在future 崩溃.另一方面,Firestore不允许子文档查询(但)或使用多个whereEqualToOR子句.

我读过很多用户的帖子,他们在寻找一种简单的方法来存储这种ID's关系时遇到了问题,在他们的Collections,Use Arraylists中使用joinsqueries会很棒,但1MB的限制限制了它的数量.

希望有人能澄清这一点,或者至少教我一些新的东西;也许我的模型只是垃圾,有一个简单易行的方法吗?或者我的模型不适用于非sql数据库.

推荐答案

无法100%确定这是否完全解决了问题,因为您的使用可能存在一些边缘情况.但是,通过5分钟的快速思考,我觉得以下几点可以解决你的问题:

你可以考虑使用类似Instagram的模型.如果我的记忆力很好,他们使用的是基于events的集合.在这个特定的上下文中,events指的是用户采取的所有行动.comment是个事件like是个事件等等.

这将使您总共需要三个主要集合.

users
-- userID1
---- userdata (profile pic, bio etc.)
---- postsByUser : [postID1, postID2]
---- followedBy : [userID2, ... ]
---- following : [userID2, ... ]
-- userID2
---- userdata (profile pic, bio etc.)


posts
-- postID1 (timestamp, so it's sortable)
---- contents
---- author : userID1
---- authorPic : authorPicUrl
---- authorPoints : 12345
---- taggedUsers : []
---- comments
------ comment1 : { copy of comment event }
---- likes : [userID1, userID2]
-- postID2 (timestamp)
---- contents
... 


events
-- eventID1
---- type : comment
---- timestamp
---- byWhom : userID
---- toWhichPost : postID
---- contents : comment-text
-- eventID2
---- type : like
---- timestamp
---- byWhom : userID
---- toWhichPost : postID

对于您的用户简介页面,您将查询users.

对于新闻提要,您将根据您的用户在过go 1天(或任何给定的时间跨度)内关注的用户ID查询posts所有帖子,

对于活动提要页面( comments /喜欢等),您可以查询events条与您的用户ID相关的信息,这些信息仅限于最后1天(或任何给定的时间跨度)

最后,在用户滚动时查询下几天的帖子/事件(或者这些天是否没有新的活动)

再说一次,这只是一个简单的 idea ,我知道SOF的长老们通常有把他们钉在十字架上的习惯,所以请原谅我SOF的同事们,如果这个答案有缺陷:)

希望能对弗朗西斯科有所帮助,

祝好运!

Database相关问答推荐

我如何计算mongo中的多个字段?

如何在华为Appcube中创建和使用对象(模型)?

数据库约束 - 保留(keep)还是忽略(ignore)?

如何在 Angular 中使用 IndexedDB?

有没有办法使用 JPA 注释和 Hibernate 动态 Select @GeneratedValue 策略?

需要未提供的参数@ID?

如何手动卸载 Oracle?

将 .frm 和 .opt 文件导入 MySQL

PostgreSQL - 按时间戳值分组?

为什么 DynamoDB 查询中没有**not equal**比较?

在迁移中添加行

设计用于存储多人游戏的各种要求和统计数据的表格

当可伸缩性无关紧要时,NoSQL 与 SQL

nvarchar (50) 与 nvarchar (max) 的含义

显示包含特定表的所有数据库名称

我应该使用 NULL 还是空字符串来表示表列中没有数据?

存储信用卡号 - PCI?

Codeigniter - 使用多个数据库

Phonegap 离线数据库

将 NULL 插入 MySQL 时间戳