从 Firebase 中的节点查询多个用户帖子的有效方法
Efficient way to query posts of multiple users from a node in Firebase
我正在构建一个社交应用程序,允许用户相互关注并获取他们关注的用户发布的帖子的提要。目前,我计划按如下所示存储我的数据,但是,我不确定它是否会扩展。
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
"follows": {
"ghopper": true,
"eclarke": true,
"john": true
//+100 more maybe
},
},
"ghopper": { ... },
"john": { ... },
"eclarke": { ... }
//all the users....
},
"posts": {
"p1": {
"user": "eclarke",
"post": "Its a wonderful day today.",
"timestamp": 1459361875337
},
"p2": {
"user": "john",
"post": "The laptop seems to be malfunctioning.",
"timestamp": 9454361875332
},
"p3": {
"user": "ghopper",
"post": "The bus is late.",
"timestamp": 6593618235336
},
"p4": {
"user": "someotheuser",
"post": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"p5": {
"user": "eclarke",
"post": "The relay seems to be malfunctioning.",
"timestamp": 5459361875331
},
"p6": {
"user": "alovelace",
"post": "The relay seems to be malfunctioning.",
"timestamp": 3459361875334
}
//1,000,000+ posts maybe present.
}
}
所有用户都存储在 users
节点中,以及他们关注的人。所有用户发布的所有帖子都存储在节点帖子中。虽然该平台的用户可能会扩展到 1000 人,但排名第一。帖子的数量应该很容易扩展到 1,000,000+。我需要通过以下方式查询数据:
对于用户,alovelace
获取用户最近的帖子 the users
跟随。在我们的例子中,ghopper
、eclarke
和 john
的帖子。这个
必须按时间排序并分页。因为我们可能只显示 10 个帖子
一次。
对于用户“john”,在他的个人资料中显示他的所有帖子。
firebase 是适合此类用例的数据库吗?以下结构是否可扩展?还有什么我需要考虑的吗?
我最近才解决这个问题,你必须使用一种叫做 fanning 的技术。它涉及复制一些数据,但 Firebase 在一些文档中明确指出数据比时间便宜,所以如果有利的话可以复制。
在您的数据库中创建一个 timeline
节点:
{
123456: {
user: "Ada Lovelace",
posts: {
32gb2gjkb2g: {
"user": "someotheuser",
"post": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
23g23gg2g2: {
"user": "someotheuser",
"post": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
...
}
}
}
其中 123456
是 Ada lovelace 的 uid
,32gb2gjkb2g
和 23g23gg2g2
是 post 编辑的用户的 uid
。
每次用户创建 post,获取他们所有的关注者:
"ghopper": { ... },
"john": { ... },
"eclarke": { ... }
当用户 posts 时,遍历每个关注者并将它们散开到一个对象中:
this.fanoutObj= {};
followers.forEach((follower_uid) => {
this.fanoutObj['/timelines/' + follower_uid + '/' + some_post_id] = some_post_obj;
});
this.AF.database.object("/").update(this.fanoutObj);
现在您可以通过查询他们的时间线,使用他们的 uid
.
来查询用户的 posts
要获取约翰的所有 post,只需查询指定他姓名的 posts
节点。
我正在构建一个社交应用程序,允许用户相互关注并获取他们关注的用户发布的帖子的提要。目前,我计划按如下所示存储我的数据,但是,我不确定它是否会扩展。
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
"follows": {
"ghopper": true,
"eclarke": true,
"john": true
//+100 more maybe
},
},
"ghopper": { ... },
"john": { ... },
"eclarke": { ... }
//all the users....
},
"posts": {
"p1": {
"user": "eclarke",
"post": "Its a wonderful day today.",
"timestamp": 1459361875337
},
"p2": {
"user": "john",
"post": "The laptop seems to be malfunctioning.",
"timestamp": 9454361875332
},
"p3": {
"user": "ghopper",
"post": "The bus is late.",
"timestamp": 6593618235336
},
"p4": {
"user": "someotheuser",
"post": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"p5": {
"user": "eclarke",
"post": "The relay seems to be malfunctioning.",
"timestamp": 5459361875331
},
"p6": {
"user": "alovelace",
"post": "The relay seems to be malfunctioning.",
"timestamp": 3459361875334
}
//1,000,000+ posts maybe present.
}
}
所有用户都存储在 users
节点中,以及他们关注的人。所有用户发布的所有帖子都存储在节点帖子中。虽然该平台的用户可能会扩展到 1000 人,但排名第一。帖子的数量应该很容易扩展到 1,000,000+。我需要通过以下方式查询数据:
对于用户,
alovelace
获取用户最近的帖子 the users 跟随。在我们的例子中,ghopper
、eclarke
和john
的帖子。这个 必须按时间排序并分页。因为我们可能只显示 10 个帖子 一次。对于用户“john”,在他的个人资料中显示他的所有帖子。
firebase 是适合此类用例的数据库吗?以下结构是否可扩展?还有什么我需要考虑的吗?
我最近才解决这个问题,你必须使用一种叫做 fanning 的技术。它涉及复制一些数据,但 Firebase 在一些文档中明确指出数据比时间便宜,所以如果有利的话可以复制。
在您的数据库中创建一个 timeline
节点:
{
123456: {
user: "Ada Lovelace",
posts: {
32gb2gjkb2g: {
"user": "someotheuser",
"post": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
23g23gg2g2: {
"user": "someotheuser",
"post": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
...
}
}
}
其中 123456
是 Ada lovelace 的 uid
,32gb2gjkb2g
和 23g23gg2g2
是 post 编辑的用户的 uid
。
每次用户创建 post,获取他们所有的关注者:
"ghopper": { ... },
"john": { ... },
"eclarke": { ... }
当用户 posts 时,遍历每个关注者并将它们散开到一个对象中:
this.fanoutObj= {};
followers.forEach((follower_uid) => {
this.fanoutObj['/timelines/' + follower_uid + '/' + some_post_id] = some_post_obj;
});
this.AF.database.object("/").update(this.fanoutObj);
现在您可以通过查询他们的时间线,使用他们的 uid
.
要获取约翰的所有 post,只需查询指定他姓名的 posts
节点。