{
  "movies": {
    "movie1": {
      "genre": "comedy",
      "name": "As good as it gets",
      "lead": "Jack Nicholson"
    },
    "movie2": {
      "genre": "Horror",
      "name": "The Shining",
      "lead": "Jack Nicholson"
    },
    "movie3": {
      "genre": "comedy",
      "name": "The Mask",
      "lead": "Jim Carrey"
    }
  }
}
我是Firebase新手。如何从genre = 'comedy' 上的上方的数据检索结果?
我有什么选择?

最佳答案

使用Firebase's Query API,您可能会想尝试一下:

// !!! THIS WILL NOT WORK !!!
ref
  .orderBy('genre')
  .startAt('comedy').endAt('comedy')
  .orderBy('lead')                  // !!! THIS LINE WILL RAISE AN ERROR !!!
  .startAt('Jack Nicholson').endAt('Jack Nicholson')
  .on('value', function(snapshot) {
      console.log(snapshot.val());
  });
但是正如Firebase的@RobDiMarco在评论中所说:

因此,我上面的代码无法使用
我知道三种可行的方法。
1.在服务器上过滤最多的内容,在客户端上进行其余的操作
您可以做的是在服务器上执行一个orderBy().startAt()./endAt(),下拉其余数据,然后在客户端的JavaScript代码中进行过滤。
ref
  .orderBy('genre')
  .equalTo('comedy')
  .on('child_added', function(snapshot) {
      var movie = snapshot.val();
      if (movie.lead == 'Jack Nicholson') {
          console.log(movie);
      }
  });
2.添加一个属性,该属性组合了要过滤的值
如果这还不够好,则应考虑修改/扩展数据以允许用例。例如:您可以将genre + lead填充到一个仅用于此过滤器的属性中。
"movie1": {
    "genre": "comedy",
    "name": "As good as it gets",
    "lead": "Jack Nicholson",
    "genre_lead": "comedy_Jack Nicholson"
}, //...
实际上,您实际上是在以这种方式构建自己的多列索引,并且可以使用以下命令对其进行查询:
ref
  .orderBy('genre_lead')
  .equalTo('comedy_Jack Nicholson')
  .on('child_added', function(snapshot) {
      var movie = snapshot.val();
      console.log(movie);
  });
大卫·伊斯特(David East)写了一封library called QueryBase that helps with generating such properties
您甚至可以进行相对/范围查询,假设您要允许按类别和年份查询电影。您将使用以下数据结构:
"movie1": {
    "genre": "comedy",
    "name": "As good as it gets",
    "lead": "Jack Nicholson",
    "genre_year": "comedy_1997"
}, //...
然后使用以下内容查询90年代的喜剧:
ref
  .orderBy('genre_year')
  .startAt('comedy_1990')
  .endAt('comedy_2000')
  .on('child_added', function(snapshot) {
      var movie = snapshot.val();
      console.log(movie);
  });
如果您需要过滤的不只是年份,请确保按降序添加其他日期部分,例如"comedy_1997-12-25"。这样,Firebase对字符串值进行的词典编排顺序将与时间顺序相同。
属性中值的这种组合可以使用两个以上的值,但是您只能对Composite属性中的最后一个值进行范围过滤。
GeoFire library for Firebase实现了一个非常特殊的变体。该库将位置的纬度和经度组合到所谓的Geohash中,然后可以使用https://stackoverflow.com/a/34105063在Firebase上进行实时范围查询。
3.以编程方式创建自定义索引
还有另一种方法是在添加新的查询API之前做所有事情:在另一个节点中创建索引:
  "movies"
      // the same structure you have today
  "by_genre"
      "comedy"
          "by_lead"
              "Jack Nicholson"
                  "movie1"
              "Jim Carrey"
                  "movie3"
      "Horror"
          "by_lead"
              "Jack Nicholson"
                  "movie2"

可能有更多的方法。例如,此答案突出显示了另一种树形自定义索引:Cloud Firestore database

如果这些选项都不适合您,但是您仍然想将数据存储在Firebase中,则还可以考虑使用其compound queries
Cloud Firestore可以在一个查询中处理多个相等过滤器,但只能处理一个范围过滤器。在本质上,它基本上使用相同的查询模型,但是就像它会自动为您生成复合属性。请参阅ojit_a上的Firestore文档。

关于firebase - 根据Firebase中的多个where子句进行查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41646171/

10-11 03:44
查看更多