在 Firestore 中使用嵌套的单个查询
Working with nested single queries in Firestore
最近我将我的数据模型从 Firebase 移到了 Firestore。我所有的代码都在工作,但我在检索某些数据的嵌套查询方面遇到了一些丑陋的麻烦。重点是:
现在这部分我的数据模型看起来像这样(是的!另一个 followers/feed 例子):
{
"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
}
}
}
}
}
我的问题是,要检索用户提要的帖子,我应该按以下方式查询:
- 从我的 Feed 中按时间戳获取最后 X 个文档排序器
feedCol(userId).orderBy(CREATION_DATE, Query.Direction.DESCENDING).limit(limit)
之后,我应该对从列表中检索到的每个 post 执行一次查询:workoutPostCol.document(postId)
现在每个post的数据都有了,但是我想拍下作者的用户名,图片,积分..等等,在不同的Document
,因此,我应该再次对 post 列表中检索到的每个 authorId
执行另一个查询 userSocial(userId).document(toId)
最后,同样重要的是,我需要知道我的当前用户是否已经喜欢那个 post,所以我需要为每个 post(再次)并检查我的用户 ID 是否在 posts/likes/{userId}
内
现在一切正常,但认为 Firestore
的价格取决于数据库调用的数量,而且它不会使我的查询更简单,我不知道是否只是我的数据模型不适合这种数据库,我应该转向正常 SQL
或再次回到 Firebase
。
注意:我知道,将喜欢、提要等的子集合移动到我的用户或 post 文档中的数组列表中会容易得多,但是 Document 的限制是 1MB ,如果这个限制增长太多,它会在未来崩溃。另一方面 Firestore
不允许子文档查询(还)或使用多个 whereEqualTo
.
的 OR
子句
我已经阅读了很多 post 的用户,他们在寻找一种简单的方法来存储这种 ID's
关系以创建 joins
和 queries
在他们的 Collections
中,使用 Arraylists
会很棒,但 1MB 的限制限制了它。
希望有人能够澄清这一点,或者至少教我一些新东西;也许我的模型很糟糕,有一种简单易行的方法可以做到这一点吗?或者我的模型可能不适用于非 sql 数据库。
不能 100% 确定这是否能完全解决问题,因为您的使用可能存在一些边缘情况。但经过 5 分钟的快速思考,我觉得以下内容可以解决您的问题:
你可以考虑使用类似Instagram的模式。如果我没记错的话,他们使用的是基于 events
的 collection。 events
在此特定上下文中,我指的是用户执行的所有操作。所以 comment
是一个事件,like
是一个事件等等
这将使您总共需要三个主要 collection。
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
对于您的 user-bio 页面,您将查询 users
。
对于新闻提要,您将查询 posts
您的用户在过去 1 天(或任何给定时间跨度)内关注的用户 ID 的所有帖子,
对于 activity 提要页面(评论/喜欢等),您将查询 events
与您的用户 ID 相关的限制在过去 1 天(或任何给定的时间跨度)
最终在用户滚动时查询接下来几天的帖子/事件(或者如果那几天没有新的activity)
再一次,这只是一个快速的想法,我知道 SOF 的长老们通常习惯于将它们钉在十字架上,所以如果这个答案有缺陷,请原谅 SOF 的同胞们:)
希望对 Francisco 有所帮助,
祝你好运!
最近我将我的数据模型从 Firebase 移到了 Firestore。我所有的代码都在工作,但我在检索某些数据的嵌套查询方面遇到了一些丑陋的麻烦。重点是:
现在这部分我的数据模型看起来像这样(是的!另一个 followers/feed 例子):
{
"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
}
}
}
}
}
我的问题是,要检索用户提要的帖子,我应该按以下方式查询:
- 从我的 Feed 中按时间戳获取最后 X 个文档排序器
feedCol(userId).orderBy(CREATION_DATE, Query.Direction.DESCENDING).limit(limit)
之后,我应该对从列表中检索到的每个 post 执行一次查询:
workoutPostCol.document(postId)
现在每个post的数据都有了,但是我想拍下作者的用户名,图片,积分..等等,在不同的
Document
,因此,我应该再次对 post 列表中检索到的每个authorId
执行另一个查询userSocial(userId).document(toId)
最后,同样重要的是,我需要知道我的当前用户是否已经喜欢那个 post,所以我需要为每个 post(再次)并检查我的用户 ID 是否在
posts/likes/{userId}
内
现在一切正常,但认为 Firestore
的价格取决于数据库调用的数量,而且它不会使我的查询更简单,我不知道是否只是我的数据模型不适合这种数据库,我应该转向正常 SQL
或再次回到 Firebase
。
注意:我知道,将喜欢、提要等的子集合移动到我的用户或 post 文档中的数组列表中会容易得多,但是 Document 的限制是 1MB ,如果这个限制增长太多,它会在未来崩溃。另一方面 Firestore
不允许子文档查询(还)或使用多个 whereEqualTo
.
OR
子句
我已经阅读了很多 post 的用户,他们在寻找一种简单的方法来存储这种 ID's
关系以创建 joins
和 queries
在他们的 Collections
中,使用 Arraylists
会很棒,但 1MB 的限制限制了它。
希望有人能够澄清这一点,或者至少教我一些新东西;也许我的模型很糟糕,有一种简单易行的方法可以做到这一点吗?或者我的模型可能不适用于非 sql 数据库。
不能 100% 确定这是否能完全解决问题,因为您的使用可能存在一些边缘情况。但经过 5 分钟的快速思考,我觉得以下内容可以解决您的问题:
你可以考虑使用类似Instagram的模式。如果我没记错的话,他们使用的是基于 events
的 collection。 events
在此特定上下文中,我指的是用户执行的所有操作。所以 comment
是一个事件,like
是一个事件等等
这将使您总共需要三个主要 collection。
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
对于您的 user-bio 页面,您将查询 users
。
对于新闻提要,您将查询 posts
您的用户在过去 1 天(或任何给定时间跨度)内关注的用户 ID 的所有帖子,
对于 activity 提要页面(评论/喜欢等),您将查询 events
与您的用户 ID 相关的限制在过去 1 天(或任何给定的时间跨度)
最终在用户滚动时查询接下来几天的帖子/事件(或者如果那几天没有新的activity)
再一次,这只是一个快速的想法,我知道 SOF 的长老们通常习惯于将它们钉在十字架上,所以如果这个答案有缺陷,请原谅 SOF 的同胞们:)
希望对 Francisco 有所帮助,
祝你好运!