基于firebase中多个where子句的查询 [英] Query based on multiple where clauses in firebase

查看:647
本文介绍了基于firebase中多个where子句的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  {
movies:{
movie1:{
genre:comedy,
name :
lead:Jack Nicholson
},
movie2:{
genre:Horror,
name:The Shining,
lead:Jack Nicholson
},
movie3:{
流派:喜剧,
name:The Mask,
lead:Jim Carrey
}
}
}

我是Firebase新手。如何从上面的数据检索结果,其中genre ='喜剧'AND lead ='Jack Nicholson'

我有什么选择?提前致谢。

解决方案

使用,您可能会试试这个:

  // !!!这将无法正常工作! 
ref
.orderBy('genre')
.startAt('comedy')。endAt('comedy')
.orderBy('lead')//这条线将升起一个错误!
.startAt('Jack Nicholson')。endAt('Jack Nicholson')
.on('value',function(snapshot){
console.log(snapshot.val()) ;
});

但是Firebase的@RobDiMarco在评论中说:


多个 orderBy()调用会抛出错误

所以我的代码无法正常工作



我知道有三种方法可行。

1。在服务器上过滤大部分内容,在客户端执行其他操作。



你可以执行一个 orderBy .startAt()./ endAt(),在客户端上拉下剩下的数据并用JavaScript代码过滤。
$ b

  ref 
.orderBy('genre')
.equalTo '喜剧')
.on('child_added',function(snapshot){
var movie = snapshot.val();
if(movie.lead =='Jack Nicholson'){
console.log(movie);
}
});



2。添加一个属性,该属性结合了您要过滤的值



如果这样做不够好,您应该考虑修改/扩展数据以允许您的用例。信息中信息内读范范范中内的数范范信息范范中范范内信息

 movie1:{
genre:comedy,
name
lead:Jack Nicholson,
genre_lead:comedy_Jack Nicholson
},...


您本质上是以这种方式构建您自己的多列索引,并可以使用以下查询:

  ref 
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added',function快照){
var movie = snapshot.val();
console.log(movie);
});

David East写了一个

你甚至可以做相对/范围查询,比如说你希望允许按类别和年份查询电影。你可以使用这个数据结构:

$ $ p $ movie1:{
genre:comedy,$
lead:Jack Nicholson,
genre_year:comedy_1997
},...

然后查询90年代的喜剧片:

< pre $ 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在字符串值上的字典顺序将与时间顺序相同。



这个属性中的值的组合可以使用两个以上的值,但是您只能对组合属性中的最后一个值进行范围过滤。



一个非常特殊的变体是由 GeoFire库为Firebase 。这个图书馆将一个地点的经度和纬度组合成一个所谓的 Geohash ,然后就可以用于在Firebase上进行实时范围查询。

3。以编程方式创建自定义索引另一种方法是在添加新的Query API之前完成所有工作:在不同节点中创建索引:



$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
by_lead
Jack Nicholson
movie1
Jim Carrey
movie3
恐怖
by_lead
Jack Nicholson
movie2

方法。例如,此答案突出显示了另一种树状自定义索引: https://stackoverflow.com/a/34105063


{
"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"
    }
  }  
 }

I am Firebase newbie. How can I retrieve a result from the data above where genre = 'comedy' AND lead = 'Jack Nicholson' ?

What options do I have? Thanks in advance.

解决方案

Using Firebase's new Query API, you might be tempted to try this:

// !!! 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()); 
  });

But as @RobDiMarco from Firebase says in the comments:

multiple orderBy() calls will throw an error

So my code above will not work.

I know of three approaches that will work.

1. filter most on the server, do the rest on the client

What you can do is execute one orderBy().startAt()./endAt() on the server, pull down the remaining data and filter that in JavaScript code on your client.

ref
  .orderBy('genre')
  .equalTo('comedy')
  .on('child_added', function(snapshot) { 
      var movie = snapshot.val();
      if (movie.lead == 'Jack Nicholson') {
          console.log(movie);
      }
  });

2. add a property that combines the values that you want to filter on

If that isn't good enough, you should consider modifying/expanding your data to allow your use-case. For example: you could stuff genre+lead into a single property that you just use for this filter.

"movie1": {
    "genre": "comedy",
    "name": "As good as it gets",
    "lead": "Jack Nicholson",
    "genre_lead": "comedy_Jack Nicholson"
},...

You're essentially building your own multi-column index that way and can query it with:

ref
  .orderBy('genre_lead')
  .equalTo('comedy_Jack Nicholson')
  .on('child_added', function(snapshot) { 
      var movie = snapshot.val();
      console.log(movie);
  });

David East has written a library called QueryBase that helps with generating such properties.

You could even do relative/range queries, let's say that you want to allow querying movies by category and year. You'd use this data structure:

"movie1": {
    "genre": "comedy",
    "name": "As good as it gets",
    "lead": "Jack Nicholson",
    "genre_year": "comedy_1997"
},...

And then query for comedies of the 90s with:

ref
  .orderBy('genre_year')
  .startAt('comedy_1990')
  .endAt('comedy_2000')
  .on('child_added', function(snapshot) { 
      var movie = snapshot.val();
      console.log(movie);
  });

If you need to filter on more than just the year, make sure to add the other date parts in descending order, e.g. "comedy_1997-12-25". This way the lexicographical ordering that Firebase does on string values will be the same as the chronological ordering.

This combining of values in a property can work with more than two values, but you can only do a range filter on the last value in the composite property.

A very special variant of this is implemented by the GeoFire library for Firebase. This library combines the latitude and longitude of a location into a so-called Geohash, which can then be used to do realtime range queries on Firebase.

3. create a custom index programmatically

Yet another alternative is to do what we've all done before this new Query API was added: create an index in a different node:

  "movies"
      // the same structure you have today
  "by_genre"
      "comedy"
          "by_lead"
              "Jack Nicholson"
                  "movie1"
              "Jim Carrey"
                  "movie3"
      "Horror"
          "by_lead"
              "Jack Nicholson"
                  "movie2"

There are probably more approaches. For example, this answer highlights an alternative tree-shaped custom index: https://stackoverflow.com/a/34105063

这篇关于基于firebase中多个where子句的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆