编辑:不使用额外参数的更简单方法
查询
以下是无需使用额外参数即可执行此操作的查询:
- 找到没有
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: 如果您经常运行这些查询,则可能值得根据 creation 的存在将 /companies 的子级分成两个箱。这样一来,您就可以分别读取这两个段,而无需依赖查询。
工厂
这是修改后的工厂的样子(我已经修改了 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;
}
});
是的,可以在返回的数据快照上调用.on('child_added')。见DataSnapshot.ref()。
使用额外参数的原始答案:
(留作参考)
另一种方法是向具有creation 的companies 的子代添加另一个名为hasCreation 的参数,并通过该参数进行查询。
数据
- 查询将是
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
}
}
规则
您可以像这样将".indexOn" : "hasCreation" 添加到您的规则中:
"so:29179389":{
".read" : true,
".write" : true,
"companies" : {
".indexOn" : "hasCreation"
}
}
公司工厂
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;
}
});
控制器
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;
});
}
});
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>