最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firebase: How do I retrieve records from my data for which a specific key exists? - Stack Overflow

programmeradmin2浏览0评论

I have data in firebase that looks like this:

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

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

      "facebook": {
      },

      "apple": {
      }
    }
  }
}

There are tens of thousands of records under panies key. How do i efficiently execute following queries?

How do I query only the records for which key creation is present under their name?

How do I query only the records that DO NOT have key creation present under their name?

I also want to call .on('child_added') on the returned result set so that I can process only those specific records later on. Is it possible?

I have data in firebase that looks like this:

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

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

      "facebook": {
      },

      "apple": {
      }
    }
  }
}

There are tens of thousands of records under panies key. How do i efficiently execute following queries?

How do I query only the records for which key creation is present under their name?

How do I query only the records that DO NOT have key creation present under their name?

I also want to call .on('child_added') on the returned result set so that I can process only those specific records later on. Is it possible?

Share Improve this question edited Mar 21, 2015 at 18:53 Waseem asked Mar 21, 2015 at 4:56 WaseemWaseem 8,4029 gold badges44 silver badges55 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 12

EDIT: Simpler way without using an extra parameter

Queries

Here are the queries to do this without having to use an extra parameter:

  • Find the panies without creation:
    • var ref = new Firebase(fbUrl+'/panies').orderByChild("creation").equalTo(null);
  • Find the panies with creation:
    • var ref = new Firebase(fbUrl+'/panies').orderByChild("creation").startAt(!null);
  • You would add ".indexOn": "creation" to the rules.

Edit 2: I was curious, so I pushed 11,000 records to /panies2 (half with creation children, half without). I was able to retrieve 5500 matching records in ~4 seconds using the above queries (or one of the variants I've shown below).

Edit 3: If you're running these queries frequently, it might be worth it to separate children of /panies into two bins based the presence of creation. That way, you can read the two segments separately without having to rely on queries.

Factory

Here is what the revised factory would look like (I've revised the PLNKR to match):

app.factory("CompaniesFactory",function($q, fbUrl){
  return function(hasCreation){
    var deferred = $q.defer();
    var ref = new Firebase(fbUrl+'/panies').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;
  }
});

And yes, it is possible to call .on('child_added') on the returned dataSnapshot. See DataSnapshot.ref().



Original answer using an extra parameter:

(Keeping this for reference)

Another way to do it would be by adding another parameter called hasCreation to children of panies that have creation, and query by that.

Data

  • The query would then be var ref = new Firebase(fbUrl+'/panies').orderByChild("hasCreation").equalTo(hasCreation);
    • If hasCreation in the query is null, the query will return the panies without a hasCreation child.
    • If hasCreation in the query is true, the query will return the panies with hasCreation===true.
{
  "pany1" : {
    "creation" : {
      "name" : "pany1"
    },
    "hasCreation" : true
  },
  "pany2" : {
    "name" : "pany2"
  },
  "pany3" : {
    "name" : "pany3"
  },
  "pany4" : {
    "creation" : {
      "name" : "pany4"
    },
    "hasCreation" : true
  }
}

Rules

You would add the ".indexOn" : "hasCreation" to your rules like so:

  "so:29179389":{
    ".read" : true,
    ".write" : true,
    "panies" : {
      ".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+'/panies').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 panies = new CompaniesFactory(hasCreation).then(function(data){
     console.log(data);
     $scope.panies = 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>
    {{panies}}
  </div>
</body>

What I would do, is I would set a condition to verify if your xxx.firebaseio./Application/panies/______/creation exists. In a empty blank, you can set for loop to irritate over the array of panies.Then, you can create two arrays with angular.forEach: one including those panies which do have 'creation', and the other array in which the elements do not include the 'creation'.

Hope that helps :)

Edit:
There is another approach to this question, in this thread:
Angularfire: how to query the values of a specific key in an array?

发布评论

评论列表(0)

  1. 暂无评论