我使用Firebase构建了一个包含两个模型的应用A
和B
:
A
与B
之间存在一对多关系(A
有许多B
)。 A
和B
需要易于查询,因此我需要一种方法来获取具有满足条件的属性的所有A
模型。与B
相同。B
有一个属性createdAt
(永远不会更改)和一个属性status
(它会不时更改)我希望列出所有Bs
由特定A
拥有,status
和/或createdAt
属性符合某些条件。Bs
是私有的,只能由经过身份验证的用户阅读,并且可以阅读他们所属的A
(用户可以阅读b1
,如果可以阅读a1
}和a1
属于b1
)。关注Firebase guidelines,我的第一次尝试是做这样的事情:
"As": {
"a1": {
...
Bs: {
"b1": true,
...
},
},
...
},
"Bs": {
"b1": {
...,
"status": "OPEN",
"createdAt": 1464249410579,
},
...
},
此解决方案的问题是,要访问属于Bs
状态为a1
且不超过一个月的OPEN
,我必须访问a1.Bs
,获取所有ID,然后逐个访问Bs
(这很好,根据Firebase guidelines)然后过滤它们以查明它们是否满足我的条件,我发现它非常低效的。
有关如何执行此操作的任何建议吗?
答案 0 :(得分:1)
在思考了一下后,我们提出了这个解决方案:
"As": {
"a1": {
...
Bs: {
"b1": { "status": "OPEN", "createdAt": 1464249410579 },
...
},
},
...
},
"Bs": {
"b1": {
...,
"status": "OPEN",
"createdAt": 1464249410579,
},
...
},
此解决方案允许我们保持数据库的结构平坦,以便数据As
和Bs
可由例如管理员用户搜索和列出。它还尝试最小化数据重复,它可以用于我们希望包含在查询中的任意数量的属性。
要抓取属于Bs
的{{1}}:
A
要抓取属于ref.child('as/:aId/bs').once('value')
.then(snapshot => snapshot.forEach(...) // Access /bs/:bId where :bId = snapshotItem.key()
Bs
的{{1}},A
为status
:
OPEN
要抓取属于ref.child('as/:aId/bs')
.orderByChild('status')
.equalTo('OPEN')
.once('value')
.then(snapshot => snapshot.forEach(...) // Access /bs/:bId where :bId = snapshotItem.key()
的{{1}},Bs
A
,status
符合条件:
OPEN
在最后一种情况下,我们必须在客户端进行一些过滤,但这是由于Firebase的限制,我不认为我们可以避免它。无论如何,这是在id的数组上完成的,而不是在模型本身上完成的,它可能有20或30个属性,因此我们避免使用我们不需要的完整模型。
答案 1 :(得分:0)
我会做那样的事情:
"As": {
"a1": {
...
},
...
},
"Bs": {
"a1" : {
"b1": {
"status": "OPEN",
"createdAt": 1464249410579,
},
},
},
a1
是你的关键A
通过这种方式,您可以轻松查询属于bs
a
这是我建议的here
答案 2 :(得分:0)
我会对此采取行动。
As
a1
Bs
b1: true
b2: true
a2
Bs
b2: true
Bs
b1:
"open_a1": 1464249410579
b2:
"open_a1": 1464249410590
"open_a2": 1464249410595
此结构允许您的代码从As节点知道链接到a1
的所有B您可以查询Bs以查找所有open_a1<一个月
ref.queryByChild("open_a1").queryStaringAtValue(today)
.queryEndingAtValue(one month from today)
这是完全未经测试的,所以我可能需要修改解决方案。