Firebase:如何从存储特定密钥的数据中检索记录?

Was*_*eem 5 javascript angularjs firebase angularfire

我在firebase中有数据如下所示:

"application": {
  "companies": {
    "firebase": {
      "creation": {
        "name": "Firebase Inc",
        "location": "USA"
      },

      "google": {
        "creattion": {
          "name": "Google Inc",
          "location": "USA"
        }
      }

      "facebook": {
      },

      "apple": {
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

companies密钥下有成千上万的记录.我如何有效地执行以下查询?

如何仅查询creation其名称下存在密钥的记录?

如何只查询creation名称下没有密钥的记录?

我还想调用.on('child_added')返回的结果集,以便稍后我只能处理那些特定的记录.可能吗?

Sin*_*lel 11

编辑:更简单的方式,而无需使用额外的参数

查询

以下是无需使用额外参数即可执行此操作的查询:

  • 找到没有 的公司creation:
    • var ref = new Firebase(fbUrl+'/companies').orderByChild("creation").equalTo(null);
  • 找到公司 creation:
    • var ref = new Firebase(fbUrl+'/companies').orderByChild("creation").startAt(!null);
  • 您将添加".indexOn": "creation"规则.

编辑2:我很好奇,所以我把11,000条记录推到了/companies2(一半有creation孩子,有一半没有).我可以使用上面的查询(或我在下面显示的变体之一)在~4秒内检索5500个匹配记录.

编辑3:如果您经常运行这些查询,那么/companies根据存在的情况将孩子分成两个箱子可能是值得的creation.这样,您可以单独阅读这两个段,而无需依赖查询.

这是修改后的工厂的样子(我修改了PLNKR以匹配):

app.factory("CompaniesFactory",function($q, fbUrl){
  return function(hasCreation){
    var deferred = $q.defer();
    var ref = new Firebase(fbUrl+'/companies').orderByChild("creation");
    var query;
    if (hasCreation) {
      query = ref.startAt(!null);
      // or: 
      // query = ref.startAt(true);
    } else {
      query = ref.equalTo(null);
      // or:
      // query = ref.endAt(!null);
      // query = ref.endAt(true);
    }
    query.once("value", function(dataSnapshot){
      deferred.resolve(dataSnapshot.val());
    }, function (error) {
      deferred.reject(error);
    });
    return deferred.promise;
  }
});
Run Code Online (Sandbox Code Playgroud)

是的,可以调用.on('child_added')返回的dataSnapshot.请参见DataSnapshot.ref().



使用额外参数的原始答案:

(保留此参考)

另一种方式来做到这一点是通过添加另一个参数调用hasCreation到的孩子companiescreation由,和查询.

数据

  • 然后查询将是 var ref = new Firebase(fbUrl+'/companies').orderByChild("hasCreation").equalTo(hasCreation);
    • 如果hasCreation在查询中null,查询将返回没有hasCreation子项的公司.
    • 如果hasCreation在查询中true,查询将返回公司hasCreation===true.
{
  "company1" : {
    "creation" : {
      "name" : "company1"
    },
    "hasCreation" : true
  },
  "company2" : {
    "name" : "company2"
  },
  "company3" : {
    "name" : "company3"
  },
  "company4" : {
    "creation" : {
      "name" : "company4"
    },
    "hasCreation" : true
  }
}
Run Code Online (Sandbox Code Playgroud)

规则

您可以".indexOn" : "hasCreation"像这样添加规则:

  "so:29179389":{
    ".read" : true,
    ".write" : true,
    "companies" : {
      ".indexOn" : "hasCreation"
    }
  }
Run Code Online (Sandbox Code Playgroud)

公司工厂

app.factory("CompaniesFactory",function($q, fbUrl){
  return function(hasCreation){
    var deferred = $q.defer();
    if (!hasCreation) {
      hasCreation = null;
    }
    var ref = new Firebase(fbUrl+'/companies').orderByChild("hasCreation").equalTo(hasCreation);
    ref.once("value", function(dataSnapshot){
      deferred.resolve(dataSnapshot.val());
    });
    return deferred.promise;
  }
});
Run Code Online (Sandbox Code Playgroud)

调节器

app.controller('HomeController',function($scope,fbUrl,CompaniesFactory) {
 $scope.getCompanies = function(hasCreation) {
  var companies = new CompaniesFactory(hasCreation).then(function(data){
     console.log(data);
     $scope.companies = data;
   });
 }
});
Run Code Online (Sandbox Code Playgroud)

HTML

<body ng-app="sampleApp">
  <div ng-controller="HomeController">
    <button ng-click="getCompanies(true)">Find with creation</button>
    <button ng-click="getCompanies(false)">Find without creation</button>
    <h2>Companies:</h2>
    {{companies}}
  </div>
</body>
Run Code Online (Sandbox Code Playgroud)