查询以匹配Firebase中存在嵌套子值的记录

时间:2016-04-11 13:44:46

标签: jquery firebase firebase-realtime-database

有没有办法在Firebase中执行'$ in'查询。需要知道这个人是否在json的“技能”中有技巧jquery。粘贴样本json文件。

    {
   "firstName":"John",
   "lastName":"Smith",
   "age":25,
   "skills":[
      "jquery",
      "c++",
      "mongo",
      "firebase"
   ],
   "address":{
      "streetAddress":"21 2nd Street",
      "city":"New York",
      "state":"NY",
      "postalCode":"10021"
   }
}

1 个答案:

答案 0 :(得分:3)

使用当前结构,查询需要迭代技能数组,这不是Firebase服务器支持的操作。这是Firebase建议不要使用数组的众多原因之一。

如果您将数据结构更改为:

{
   "firstName":"John",
   "lastName":"Smith",
   "age":25,
   "skills":{
      "jquery": true,
      "c++": true,
      "mongo": true,
      "firebase": true
   },
   "address":{
      "streetAddress":"21 2nd Street",
      "city":"New York",
      "state":"NY",
      "postalCode":"10021"
   }
}

您可以将查询编写为:

ref.child('users').orderByChild('skills/jquery').equalTo(true)

查询可能就是您想要的,但它要求您添加如下索引:

"users" {
  "$uid": {
    ".indexOn": ['skills/jquery', 'skills/c++', 'skills/mongo', 'skills/firebase']
  }
}

这些索引很快失控,无法以编程方式添加。这通常表明您的数据结构是错误的。

NoSQL数据库的正确数据结构通常反映了您的应用程序的用例。您需要找到特定技能的用户,在这种情况下,您应该保留每种技能的用户列表。

"uids_per_skill": {
  "jquery": {
    "uidOfJohnSmith": true,
    "uidOfAravchr": true
  },
  "c++": {
    "uidOfJohnSmith": true
  },
  "mongo": {
    "uidOfJohnSmith": true,
    "uidOfAravchr": true
  },
  "firebase": {
    "uidOfJohnSmith": true,
    "uidOfPuf": true
  }
}

现在,您可以通过简单的查找(而不是查询)来确定了解jQuery的用户列表:

ref.child('uids_per_skill').child('jquery').on('value', function(userKeys) {
  userKeys.forEach(function(userKey) {
    ref.child('users').child(userKey.key()).once('value', function(userSnapshot) {
      console.log(userSnapshot.val());
    });
  });
});

这种类型的数据建模称为非规范化,并在Firebase blog post on the topicFirebase documentation on structuring data和这个伟大的article on NoSQL data modeling中进行了介绍。