Firebase:如何从存在特定键的数据中检索记录?
Firebase: How do I retrieve records from my data for which a specific key exists?
我在 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')
,这样我以后就可以只处理那些特定的记录。可能吗?
我会做的是设置一个条件来验证您的 xxx.firebaseio.com/Application/companies/______/creation 是否存在。在空白处,可以设置for循环遍历companies.Then的数组,可以创建两个angular.forEach的数组:一个包含那些有'creation'的公司,另一个元素不包含 'creation'.
的数组
希望对您有所帮助:)
编辑:
这个问题还有另一种方法,在这个线程中:
Angularfire: how to query the values of a specific key in an array?
编辑:不使用额外参数的更简单方法
查询
以下是无需使用额外参数即可执行此操作的查询:
- 查找没有的公司
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
children,一半没有).使用上述查询(或我在下面显示的变体之一),我能够在大约 4 秒内检索到 5500 条匹配记录。
编辑 3: 如果您经常 运行 这些查询,将 children 和 /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;
}
});
是的,可以在 returned dataSnapshot 上调用 .on('child_added')
。参见 DataSnapshot.ref()。
使用额外参数的原始答案:
(留作参考)
另一种方法是将另一个名为 hasCreation
的参数添加到具有 creation
的 companies
的 children 中,然后通过该参数进行查询。
数据
- 查询将是
var ref = new Firebase(fbUrl+'/companies').orderByChild("hasCreation").equalTo(hasCreation);
- 如果查询中的
hasCreation
是null
,查询将return没有hasCreation
的公司child。
- 如果查询中的
hasCreation
为 true
,则查询将 return 包含 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>
我在 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')
,这样我以后就可以只处理那些特定的记录。可能吗?
我会做的是设置一个条件来验证您的 xxx.firebaseio.com/Application/companies/______/creation 是否存在。在空白处,可以设置for循环遍历companies.Then的数组,可以创建两个angular.forEach的数组:一个包含那些有'creation'的公司,另一个元素不包含 'creation'.
的数组希望对您有所帮助:)
编辑:
这个问题还有另一种方法,在这个线程中:
Angularfire: how to query the values of a specific key in an array?
编辑:不使用额外参数的更简单方法
查询
以下是无需使用额外参数即可执行此操作的查询:
- 查找没有的公司
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
children,一半没有).使用上述查询(或我在下面显示的变体之一),我能够在大约 4 秒内检索到 5500 条匹配记录。
编辑 3: 如果您经常 运行 这些查询,将 children 和 /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;
}
});
是的,可以在 returned dataSnapshot 上调用 .on('child_added')
。参见 DataSnapshot.ref()。
使用额外参数的原始答案:
(留作参考)
另一种方法是将另一个名为 hasCreation
的参数添加到具有 creation
的 companies
的 children 中,然后通过该参数进行查询。
数据
- 查询将是
var ref = new Firebase(fbUrl+'/companies').orderByChild("hasCreation").equalTo(hasCreation);
- 如果查询中的
hasCreation
是null
,查询将return没有hasCreation
的公司child。 - 如果查询中的
hasCreation
为true
,则查询将 return 包含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>