Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase多对多非规范化_Firebase - Fatal编程技术网

Firebase多对多非规范化

Firebase多对多非规范化,firebase,Firebase,我有一个非常基本的数据结构 事件 话题 我希望能够轻松地显示(查询) 活动拥有哪些主题 哪些活动涉及一个主题 本月最受欢迎的话题是什么 我对我的活动结构很满意,比如 /events/880088/topics.json* ["Firebase", "Cloud"] 但我很难理解如何构造/topics节点。我有点想和这样的人一起去 /topics/Firebase {"12345":true,"88088":true} 然后,如果在更新事件的主题集合时,我必须迭代所有/topics/节点,

我有一个非常基本的数据结构

  • 事件
  • 话题
我希望能够轻松地显示(查询)

  • 活动拥有哪些主题

  • 哪些活动涉及一个主题

  • 本月最受欢迎的话题是什么

  • 我对我的活动结构很满意,比如

    /events/880088/topics.json*

    ["Firebase", "Cloud"]
    
    但我很难理解如何构造/topics节点。我有点想和这样的人一起去

    /topics/Firebase

    {"12345":true,"88088":true}
    
    然后,如果在更新事件的主题集合时,我必须迭代所有/topics/节点,并将/topics/{{topic}}/{{eventid}}更新为{true | null}。这似乎有点笨手笨脚

    此外,我还不知道如何提问,比如说,本月的活动涉及哪些主题

    下面评论中的示例JSBin


    *
    我知道,我知道数组是邪恶的,但我认为它们适合这个场景

    function addEvent(title, topics) {
      var event =ref.child('events').push({ title: title });
      topics.forEach(function(topic) {
        event.child('topics').child(topic).set(true);
        ref.child('topics').child(topic).child(event.key()).set(true);
      });
    }
    
    对我来说似乎很简单。对于有趣的转变,您可以使用新的(2015年9月):

    后者的代码要多一点。但这是对Firebase的一次写入操作,因此用户不可能在写入操作之间关闭应用程序

    当然,您调用这两个函数是相同的:

    addEvent('Learn all about Firebase', ['Firebase']);
    addEvent('Cloudspin', ['Firebase', 'Google', 'Cloud']);
    
    数据结构变成:

    {
      "events": {
        "-K-4HCzj_ziHkZq3Fpat": {
          "title": "Learn all about Firebase",
          "topics": {
            "Firebase": true
          }
        },
        "-K-4HCzlBFDIwaA8Ajb7": {
          "title": "Cloudspin",
          "topics": {
            "Cloud": true,
            "Firebase": true,
            "Google": true
          }
        }
      },
      "topic": {
        "Cloud": {
          "-K-4HCzlBFDIwaA8Ajb7": true
        },
        "Firebase": {
          "-K-4HCzj_ziHkZq3Fpat": true,
          "-K-4HCzlBFDIwaA8Ajb7": true
        },
        "Google": {
          "-K-4HCzlBFDIwaA8Ajb7": true
        }
      }
    }
    
    查询/报告 对于Firebase(以及大多数NoSQL数据库),您通常必须调整数据结构,以适应您希望在其上执行的报告

    安倍最近就这一点写了一个很好的答案,所以请务必阅读:

    更新:更改事件的主题 如果要更改现有事件的主题,此函数是实现此目的的一种方法:

    function updateEventTopics(event, newTopics) {
      newTopics.sort();
      var eventId = event.key();
      var updates = {};
      event.once('value', function(snapshot) {
        var oldTopics = Object.keys(snapshot.val().topics).sort();
        var added = newTopics.filter(function(t) { return oldTopics.indexOf(t) < 0; }), 
            removed = oldTopics.filter(function(t) { return newTopics.indexOf(t) < 0; });
        added.forEach(function(topic) {
          updates['events/'+eventId+'/topics/'+topic] = true;
          updates['topic/'+topic+'/'+eventId] = true;
        });
        removed.forEach(function(topic) {
          updates['events/'+eventId+'/topics/'+topic] = null;
          updates['topic/'+topic+'/'+eventId] = null;
        });
        ref.update(updates);
      });
    }
    
    调用
    changeventtopics()
    将导致此
    update()


    我写了一个构建您的结构的小片段:。你能用你使用的代码编辑你的问题吗?你觉得什么是笨拙的?下面是一个简单的答案。好。。。不是真正的答案,但希望有一些有用的代码片段可以与.ooo进行比较。多位置更新。那是霍特。谢谢你。:)下一步是我有点结巴,比如说我以后换话题。如何从主题集合中删除事件元素?在不扫描所有主题节点的情况下,是否可以调用API来更改主题?每次代码都胜过描述。:-)(同意多地点热顺便说一句)好的,我拿了你的jsbin,修改到我的车轮从马车上掉下来的程度。好的,我添加了一个例子。请注意,我恢复了基于API的方法,因此我们可以只关注后端。更新后的jsbin在这里:完美,它发现了对我来说不明显的delta。
    function updateEventTopics(event, newTopics) {
      newTopics.sort();
      var eventId = event.key();
      var updates = {};
      event.once('value', function(snapshot) {
        var oldTopics = Object.keys(snapshot.val().topics).sort();
        var added = newTopics.filter(function(t) { return oldTopics.indexOf(t) < 0; }), 
            removed = oldTopics.filter(function(t) { return newTopics.indexOf(t) < 0; });
        added.forEach(function(topic) {
          updates['events/'+eventId+'/topics/'+topic] = true;
          updates['topic/'+topic+'/'+eventId] = true;
        });
        removed.forEach(function(topic) {
          updates['events/'+eventId+'/topics/'+topic] = null;
          updates['topic/'+topic+'/'+eventId] = null;
        });
        ref.update(updates);
      });
    }
    
    var event = addEvent('Cloudspin', Date.now() - month, ['Firebase', 'Google', 'Cloud']);
    updateEventTopics(event, ['Firebase', 'Google', 'GCP']);
    
    {
      "events/-K-93CxuCrFDxM6k0B14/topics/Cloud": null,
      "events/-K-93CxuCrFDxM6k0B14/topics/GCP": true,
      "topic/Cloud/-K-93CxuCrFDxM6k0B14": null,
      "topic/GCP/-K-93CxuCrFDxM6k0B14": true
    }