如何在Firebase JSON树中表示双向关系?

警告:

>这是一个练习,以了解Firebase中更好的JSON数据库设计
>这不一定是现实的

我在用户和门钥匙之间有两种关系.我想了解:

>如何直观地表示这种关系(我可以想象它只是两个独立的树)
>这对Firebase有何影响,用户和门钥匙都是父节点“myparentnodename”的子节点吗?
>如果我以这种方式对数据库建模,那么感觉非常低效,因为每次我查询子节点“用户”时,我都会得到所有用户的回复.或者我错了?是否可以仅返回与特定用户匹配的数据?例如.获取用户“user = user1”的位置?我们可以做嵌套查询吗?例如将先前的条件与门钥匙上的某些条件结合起来,以便返回的JSON对象仅与“user1”节点中包含的门钥匙相关?

解决方法

这是一个很长的答案,因为你的问题实际上是关于5个不同的问题.

根节点是: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

如果查询key_3,则可以看到它们属于用户0和2

你的问题是

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.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)