swift firebase嵌套子项计数
在这里这样的一个结构中,我必须计算所有组中ownerId等于我的id(currentUserId)的所有发生率,有人能帮我吗 到目前为止我所做的:swift firebase嵌套子项计数,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,在这里这样的一个结构中,我必须计算所有组中ownerId等于我的id(currentUserId)的所有发生率,有人能帮我吗 到目前为止我所做的: root.child(“组”).observe(.value,其中:{(快照)位于 如果let result=snapshot.children.allObjects as?[DataSnapshot]{ 变量计数=0 为了孩子{ 让orderID=child.key作为字符串//获取自动ID self.root.child(“groups/\(or
root.child(“组”).observe(.value,其中:{(快照)位于
如果let result=snapshot.children.allObjects as?[DataSnapshot]{
变量计数=0
为了孩子{
让orderID=child.key作为字符串//获取自动ID
self.root.child(“groups/\(orderID)/”).queryOrdered(byChild:“ownerId”).queryEqual(toValue:self.currentUserId)。观察(.value,其中:{(快照:DataSnapshot!))
打印(snapshot.childrenCount,“quanti-sono”)
计数+=(Int(快照.子计数))
打印(计数)
})
}
}
})
有了这个,我可以得到一个计数,但它会更新所有周期。。。我需要我需要外部的最终值您可以通过执行
的单个观察.childAdded
类型来实现此步骤。在您的示例中,.childAdded
子节点上的.childAdded
类似于迭代所有节点的for循环
使用此配置,您可以附加一个.queryOrdered(byChild:)
和一个.queryEqual(toValue:)
:
之后,如果要计算所有子级,则需要在类上添加属性
这是一个测试示例:
要优化性能,请记住在firebase应用程序上添加.indexOn
规则:
ref.child("groups")
.queryOrdered(byChild: "ownerID")
.queryEqual(toValue: 123)
.observe(.childAdded)
{ (snap) in
print(snap)
}
希望这对你有帮助;) 火基结构的一个重要方面是对结构进行加固或整平。非规范化数据通常会使查询变得更容易,虽然从概念上讲,您正在使用的结构适用于某些任务,但它会使执行您想要的查询变得具有挑战性
因此,我建议使用另一种结构,使查询变得超级简单,而不会失去其他功能
对结构的更改如下:
"groups" : {
".indexOn" : "ownerID"
}
然后,如果要计算具有特定所有者ID的所有子组
groups
group1: true
group2: true
subgroups
subgroup1(autoid)
id
ownerId
description
belongs_to_group: "group1"
subgroup2(autoid)
id
ownerId
description
belongs_to_group: "group2"
编辑:
根据评论,这里有一种根据您当前的结构获取计数的方法。这是一个非常强大的工具,代码可以大大减少,但是为了可读性,我把它放在了冗长的地方
let subGroupsRef = self.ref.child("subgroups")
let query = subGroupsRef.queryOrdered(byChild: "ownerId").queryEqual(toValue: "their id")
query.observeSingleEvent(of: .value) { snapshot in
let count = snapshot.childrenCount
print(count)
}
失败的地方是,如果您有很多节点,因为它们最初都加载在(by.value)中,所以可以在代码中迭代。如果是几千,它工作得很好,速度也很快。欢迎使用堆栈溢出!用实际数据示例、预期结果和实际结果更新您的问题会很有帮助。看看如何在这里创建一个最小的、完整的、可验证的示例:我想说的是,如何存储组的数量是一个问题。此查询涉及子查询,并且过于复杂,无法获得简单的结果。为什么不直接在数据库中存储用户所属的组数?示例用户->UID->GroupMemberCount?然后,您可以在用户加入/离开组时更新此值。这将使整个过程更容易。此外,snapshot.childrenCount会迭代所有子项,因此如果用户是许多组的成员,则可能效率不高。Thnx Giuseppe但我在问题中写了一个错误,我遗漏了一个嵌套的子项,结构是:[code]组-KwW2gHCbWzPCQpmbfhu--kxgqygqyg2cjkieln1addclose--ownerId:[code]不幸的是,这不起作用。您建议的查询将查询每个group1、group2的ownerId的直接子节点。如果查看结构group1和group2,它们没有ownerID子节点。它是子节点的子节点/groups/group1/ownerId,not/groups/ownerId.thnx Jay,你的方式是一个很好的方式,但目前我无法更改数据库结构,用我的代码(你可以看到的代码)我可以获得计数,如果我添加一个完整的,也许我只能读取最终计数。。。“你认为呢?”马可明白了。我用一个解决方案编辑了我的答案。它可以工作,但我不是特别喜欢它,因为我不喜欢给出一个可能会因为必须加载太多节点而失败的答案。早上我可能有另一个选择。Thnx@Jay它工作得很好,请告诉我你是否找到更好的解决方案!
let subGroupsRef = self.ref.child("subgroups")
let query = subGroupsRef.queryOrdered(byChild: "ownerId").queryEqual(toValue: "their id")
query.observeSingleEvent(of: .value) { snapshot in
let count = snapshot.childrenCount
print(count)
}
let groupsRef = self.ref.child("groups")
groupsRef.observeSingleEvent(of: .value, with: { snapshot in
var count = 0
for groupChild in snapshot.children {
let groupSnap = groupChild as! DataSnapshot
for subGroupChild in groupSnap.children {
let subGroupSnap = subGroupChild as! DataSnapshot
let dict = subGroupSnap.value as! [String: Any]
let uid = dict["owner_id"] as! String
if uid == "uid_0" {
count += 1
print(count)
}
}
}
print("total found \(count)")
})