【问题标题】:Query Firebase Database with two between conditions使用两个中间条件查询 Firebase 数据库
【发布时间】:2017-02-14 14:15:14
【问题描述】:

我想知道是否可以从我的 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 在客户端应用第二个条件?

【问题讨论】:

    标签: javascript firebase firebase-realtime-database


    【解决方案1】:

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

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

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

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

    {
      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 也会这样做):

    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
      }
    });
    

    【讨论】:

    • 这真的很有趣@frank-van-puffelen !感谢您的详细回答。我听取了您的建议,并在过去一天一直在尝试学习 geoFire,但我在从 geoFire 查询返回 ID 时遇到了一点问题,想知道您是否可以在这里查看一下:@987654322 @ 再次感谢!
    • 我主要使用 Geofire 作为示例,说明如果您跳出框框思考并愿意付出努力,那么看似不可能的事情是多么可能。我永远不会想到将经度和纬度组合在一个字符串中,以使它们保持可排序。幸运的是,长度*宽度更容易计算。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多