使用两个条件

时间:2017-02-14 14:15:14

标签: javascript firebase firebase-realtime-database

我想知道是否可以从我的Firebase数据库返回值列表,其中每个元素都满足两个条件。

例如,如果我的数据库看起来像这样:

MYAPP
|_______________items
|                   |_____OshwYF72Jhd9bUw56W7d
|                   |                   |
|                   |                   |__item_name:"plank_5"
|                   |                   |__length:"120"            
|                   |                   |__width:"50"             
|                   |                            
|                   |_____KbHy4293dYgVtT9pdoW
|                   |_____PS8tgw53SnO892Jhweh
|                   |_____Gicuwy8r23ndoijdakr
|
|___customers

我想在数据库中查询长度介于100到150之间,宽度介于30-70之间的每个项目的item_name,有没有办法让我用Firebase执行此操作查询?

我已经在这里阅读了答案:Query based on multiple where clauses in firebase但是这并没有处理多个between / range条款,这就是我在上面需要的内容场景。

我在另一个答案中看到了这个插件:https://github.com/davideast/Querybasewhere子句似乎没有采用一系列值。例如:

const queriedDbRef = querybaseRef
  .where({
    length: (between 100-150),
    width: (between 30-70)
  });

这样的查询是否可能?或者我是否必须使所有项目都匹配一个条件,然后使用Javascript应用第二个条件客户端?

1 个答案:

答案 0 :(得分:3)

Firebase数据库查询只能对一个属性进行排序/过滤。这是一个在不久的将来不太可能改变的硬限制。

某些情况下,可以将多个值组合到一个属性中,例如我链接的答案或QueryBase中的答案。但是在您找到的情况下,您只能对这些值中的一个执行相对/范围查询:即最后一个。

有人(据我所知)曾经实施过多值范围查询的唯一情况是在GeoFire中,我们将位置的经度和纬度合并到一个所谓的GeoHash。我强烈建议您阅读有关geohashes的更多信息,因为它们做了一些非常独特的事情:将两个数值组合成一个字符串值,允许对其数字组件进行排序和过滤。

通过查看要组合的两个值(长度和宽度),可能可以从它们创建类似的复合字符串。但是要求您找到一种方法将两个值组合起来用于用例。我可以想到的最简单的方法是存储区域,所以length * width:

{
  items: {
    "OshwYF72Jhd9bUw56W7d": {
      item_name:"plank_5",
      length: 120, // you store length and width as strings, please fix that
      width: 50,
      area: 6000
    }
  }
}

这样你就可以过滤面积在3000(100x30)到10500(70x150)之间的物品:

var query = ref.orderBy("area").startAt(3000).endAt(10500);

此查询将匹配太多项目,因此您必须执行一些额外的过滤客户端以拒绝不匹配(Geofire执行相同的btw):

query.on("child_added", function(snapshot) {
  var item = snapshot.val();
  if (item.length >= 100 && item.length <= 150
      && item.width >= 30 && item.width <= 70) {
    // TODO: do something with the item
  }
});