>这是一个练习,以了解Firebase中更好的JSON数据库设计
>这不一定是现实的
我在用户和门钥匙之间有两种关系.我想了解:
>如何直观地表示这种关系(我可以想象它只是两个独立的树)
>这对Firebase有何影响,用户和门钥匙都是父节点“myparentnodename”的子节点吗?
>如果我以这种方式对数据库建模,那么感觉非常低效,因为每次我查询子节点“用户”时,我都会得到所有用户的回复.或者我错了?是否可以仅返回与特定用户匹配的数据?例如.获取用户“user = user1”的位置?我们可以做嵌套查询吗?例如将先前的条件与门钥匙上的某些条件结合起来,以便返回的JSON对象仅与“user1”节点中包含的门钥匙相关?
解决方法
根节点是:myparentnodename
您的用户
users uid_0 name: "William" door_keys: key_0: true key_3: true uid_2 name: "Leonard" door_keys: key_3: true key_5: true
和你的钥匙
keys key_0 uid_0: true key_3 uid_0: true uid_2: true key_5 uid_5: true
通过这种结构,所有元素都“指向”彼此.
如果您查询uid_0,您可以看到他们使用键0和3
你的问题是
every time I would query the child node “users” I would get all the
users back
那稍微不完整了.查询完成后,您通常会查询特定的内容.但是,使用Firebase,有两种方法可以检索数据:观察节点和查询.
如果要返回用户节点中的所有用户,您将通过.Value(或.ChildAdded一次为1)观察该节点.
ref = myParentNodeName let usersRef = myParentNodeName.childByAppendingPath("users") usersRef.observeEventType(.Value,withBlock: { snapshot in //.Value can return multiple nodes within the snapshot so iterate over them for child in snapshot.children { let name = child.value.objectForKey("name") as! String print(name) //prints each users name } })
请注意,上面将观察者附加到用户节点,因此该节点中的任何未来更改都将通知应用程序并将整个节点重新发送到应用程序
如果您只想要一个用户的信息,并且不想继续观察更改
ref = myParentNodeName let usersRef = myParentNodeName.childByAppendingPath("users") let thisUserRef = usersRef.childByAppendingPath("uid_2") thisUserRef.observeSingleEventOfType(.Value,withBlock: { snapshot in let name = child.value.objectForKey("name") as! String print(name) //prints each users name })
最后,查询属于uid_0的所有密钥(在这个例子中有点多余,因为我们已经知道他们从他们的节点获得了哪些密钥).如果钥匙ref还包含其他信息,如门名,门所在的建筑物或门位置,那将更合适,并且需要不同的结构,所以假设情况如此:
ref = myParentNodeName let keysRef = myParentNodeName.childByAppendingPath("keys") keysRef.queryOrderedByChild("uid_0").queryEqualToValue(true) .observeSingleEventOfType(.Value,withBlock: { snapshot in let doorLocation = child.value.objectForKey("door_location") as! String print(doorLocation) //prints each users name })
请注意,此代码是Swift,因为问题中未指定平台.
另一个问题:
Can we do nested queries? e.g. combine the prevIoUs condition with
some condition on the door keys so the JSON object returned is only
relevant to the door-keys contained in the “user1” node?
我认为你的意思是你可以查询uid_2,看看他们有哪些密钥,然后加载这些特定密钥的信息.
是!但是……(总有一个但是)
Firebase是异步的,因此在嵌套查询时必须考虑到这一点,即您需要确保在获取更多数据之前返回所有数据.因此,例如,如果您需要uid_2密钥数据,则可以在节点uid_2上观察单个事件.然后你可以拥有他们的密钥,然后可以在每个密钥上观察单个事件或类型.
从技术上讲,这将起作用,但异步数据飞来飞去,你可能最终会在其他代码上踩踏代码并在实际返回之前处理数据.
更好的选择(根据我的例子)是完全避免这种情况,并查询关键节点的uid_2密钥.
作为旁注,观察节点的开销要比查询少得多,因此如果要加载单个节点并且知道路径,请使用observe.