Firebase查询过滤谓词顺序依赖&表现得很奇怪

时间:2016-09-02 19:55:29

标签: firebase firebase-realtime-database

让我们假设数据库中的样本列表:

enter image description here

在以下摘录中,ref是:
var ref = firebase.database().ref().child('test').orderByKey();

我注意到2个查询的奇怪行为:

  1. ref.limitToFirst(2).endAt('5')
    它产生4, 5,而我预期0, 1 2件事情令人惊讶:

    1. 如果交换了谓词的顺序:ref.endAt('5').limitToFirst(2)
      结果还可以:0, 1
    2. ref.limitToLast(2).endAt('5')的结果也是4, 5 正如预期的那样,limitToLast()仍然不应与此处的limitToFirst()相同。
  2. ref.limitToLast(2).startAt('5')
    同样地,即使人们可以期待5, 6,也会8, 9。{ 和上面类似:

    1. ref.startAt('5').limitToLast(2)工作正常(8, 9
    2. ref.limitToFirst(2).startAt('5')同样的结果(5, 6
  3. 现在,它既是一个错误,也不仅仅是我不理解火棒查询。
    文档和API参考都没有提到谓词顺序的重要性。

    我在网上使用Firebase 3.X(3.3.0) 剪切用于显示结果列表:

    ref.once('value').then(function(snap) {
      snap.forEach(function(child) {
        console.log(child.key);
      });
    });
    

    抱歉没有意义的标题。如果您有更好的想法,请提交修改提案。

    修改

    Firebase 2.0.0中引入了

    limitTo*()个谓词。在它们之前它只是limit() 只有limit()和(startAt()endAt())表示从结果列表中选择的顺序,它可以原谅上面的矛盾结果(但查询正常工作与谓词交换)。

    但是,startAt()endAt()都可以同时使用,因此它们无法表示方向(或至少不应该)。

    让我们玩:

    • ref.startAt('5').endAt('9').limitToFirst(3)5, 6, 7 - 确定
    • ref.startAt('5').endAt('9').limitToLast(3)7, 8, 9 - 确定
    • ref.limitToFirst(3).startAt('5').endAt('9')ref.startAt('5').limitToFirst(3).endAt('9')
      未捕获错误:查询:无法合并startAt(),endAt()和 limit()。请改用limitToFirst()或limitToLast()。

    : - d
    我猜错了。

    编辑2:

    就像我想的那样。来自limit() docs

      

    如果与startAt()结合使用,查询将在起始点后包含指定数量的子节点。如果与endAt()结合使用,查询将在结束点之前包含指定数量的子项。

2 个答案:

答案 0 :(得分:3)

看起来这确实是一个错误。特别是,如果您执行limitToLast(...).startAt(...)limitToFirst(...).endAt(...),我们最终会撤消限制并提供不正确的结果。

简单的解决方法是始终确保您的limitToXXX()电话在查询中排在最后。这不应该是必要的,但现在将解决问题。我们将尝试在将来的版本中修复此问题。谢谢你报告这个!

答案 1 :(得分:1)

实际上,错误消息与limit()文档相结合,对已关闭的Firebase源代码有了一些了解:

如果谓词按特定顺序应用,我的赌注是limitTo*()仍然会回落到折旧limit()的实现。如果该订单改变了;使用不同的,可能更新且更正确的实现。 这可以解释我的问题中证明的所有不一致和问题。

很抱歉回答我自己的问题,但是只有在思考(并且正在玩!)之后我想出了这个。 已经提交了Firebase的门票,他们可能会在这里回答。