我在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'),以便以后只能处理那些特定的记录。是否可以?

最佳答案

编辑:更简单的方法,而无需使用额外的参数

查询

以下是无需使用额外参数即可执行此操作的查询:

  • 查找没有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子级,一半不带/companies)。使用上述查询(或下面显示的一种变体),我能够在约4秒内检索到5500条匹配记录。

    编辑3:如果您经常运行这些查询,则根据creation的存在将.on('child_added')的子级分为两个容器可能是值得的。这样,您可以分别阅读两个段,而不必依赖查询。

    工厂

    这是经过修改的工厂的外观(我已经修改了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上调用hasCreation。参见DataSnapshot.ref()



    使用额外参数的原始答案:

    (供引用)

    做到这一点的另一种方法是,将另一个名为companies的参数添加到具有creationvar ref = new Firebase(fbUrl+'/companies').orderByChild("hasCreation").equalTo(hasCreation);的子级中,然后通过该参数进行查询。

    数据
  • 然后查询将是hasCreation
  • 如果查询中的nullhasCreation,则查询将返回没有hasCreation子级的公司。
  • 如果查询中的truehasCreation===true,则查询将返回带有".indexOn" : "hasCreation"的公司。

  • {
      "company1" : {
        "creation" : {
          "name" : "company1"
        },
        "hasCreation" : true
      },
      "company2" : {
        "name" : "company2"
      },
      "company3" : {
        "name" : "company3"
      },
      "company4" : {
        "creation" : {
          "name" : "company4"
        },
        "hasCreation" : true
      }
    }
    

    规则

    您可以像这样将ojit_code添加到您的规则中:
      "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;
      }
    });
    

    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>
    

    关于javascript - Firebase:如何从数据中检索存在特定键的记录?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29179389/

    10-09 06:01