UPDATE: Easier method without the need for an additional parameter
Queries
Below are the queries that can be used to achieve this without requiring an extra parameter:
- Locate the companies without a
creation
attribute:
- Locate the companies with a
creation
attribute:
- To your rules, you should add
".indexOn": "creation"
.
Update 2: I conducted an experiment by adding 11,000 records to /companies2
(half with creation
attributes and half without). The above queries were able to retrieve 5500 matching records in about 4 seconds.
Update 3: If these queries are run frequently, segregating children of /companies
into two categories based on the presence of creation
could be beneficial. This way, the two segments can be read separately without relying heavily on queries.
Factory
Here is how the updated factory function would look like (the PLNKR has been modified to reflect this):
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);
} else {
query = ref.equalTo(null);
}
query.once("value", function(dataSnapshot){
deferred.resolve(dataSnapshot.val());
}, function (error) {
deferred.reject(error);
});
return deferred.promise;
}
});
It is indeed possible to call .on('child_added')
on the returned dataSnapshot. Refer to DataSnapshot.ref() for more details.
Original response utilizing an additional parameter:
(Maintaining this for future reference)
An alternative approach involves introducing another parameter named hasCreation
to the child elements of companies
that possess the creation
property, allowing for querying based on this criterion.
Data
{
"company1" : {
"creation" : {
"name" : "company1"
},
"hasCreation" : true
},
"company2" : {
"name" : "company2"
},
"company3" : {
"name" : "company3"
},
"company4" : {
"creation" : {
"name" : "company4"
},
"hasCreation" : true
}
}
Rules
To include ".indexOn" : "hasCreation"
in your rules, do as shown below:
"so:29179389":{
".read" : true,
".write" : true,
"companies" : {
".indexOn" : "hasCreation"
}
}
Companies Factory
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;
}
});
Controller
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>