我在firebase中的数据如下所示:
"application": {
"companies": {
"firebase": {
"creation": {
"name": "Firebase Inc",
"location": "USA"
},
"google": {
"creattion": {
"name": "Google Inc",
"location": "USA"
}
}
"facebook": {
},
"apple": {
}
}
}
}
companies
键下有数万条记录。我如何有效地执行以下查询?
如何仅查询其名称下存在键creation
的记录?
如何只查询名称中没有密钥creation
的记录?
我还想在返回的结果集上调用.on('child_added')
,以便稍后我只能处理这些特定的记录。有可能吗?
答案 0 :(得分: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;
}
});
是的,可以在返回的dataSnapshot上调用.on('child_added')
。请参阅DataSnapshot.ref()。
(保留此内容供参考)
另一种方法是向hasCreation
的{{1}}子项添加另一个名为companies
的参数,并对其进行查询。
creation
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;
});
}
});
答案 1 :(得分:0)
我会做什么,是否会设置条件来验证您的xxx.firebaseio.com/Application/companies/______/creation是否存在。在一个空白的空白处,您可以设置for循环以激怒公司阵列。然后,您可以使用angular.forEach创建两个阵列:一个包括那些有创建'和另一个阵列的公司其中的元素不包括“创作”。
希望有所帮助:)
编辑:
在这个主题中还有另一种解决这个问题的方法:
Angularfire: how to query the values of a specific key in an array?