让我们假设数据库中的样本列表:
在以下摘录中,ref
是:
var ref = firebase.database().ref().child('test').orderByKey();
我注意到2个查询的奇怪行为:
ref.limitToFirst(2).endAt('5')
它产生4, 5
,而我预期0, 1
2件事情令人惊讶:
ref.endAt('5').limitToFirst(2)
,0, 1
ref.limitToLast(2).endAt('5')
的结果也是4, 5
正如预期的那样,limitToLast()
仍然不应与此处的limitToFirst()
相同。 ref.limitToLast(2).startAt('5')
同样地,即使人们可以期待5, 6
,也会8, 9
。{
和上面类似:
ref.startAt('5').limitToLast(2)
工作正常(8, 9
)ref.limitToFirst(2).startAt('5')
同样的结果(5, 6
)现在,它既是一个错误,也不仅仅是我不理解火棒查询。
文档和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')
→: - d
我猜错了。
编辑2:
就像我想的那样。来自limit()
docs:
如果与startAt()结合使用,查询将在起始点后包含指定数量的子节点。如果与endAt()结合使用,查询将在结束点之前包含指定数量的子项。
答案 0 :(得分:3)
看起来这确实是一个错误。特别是,如果您执行limitToLast(...).startAt(...)
或limitToFirst(...).endAt(...)
,我们最终会撤消限制并提供不正确的结果。
简单的解决方法是始终确保您的limitToXXX()
电话在查询中排在最后。这不应该是必要的,但现在将解决问题。我们将尝试在将来的版本中修复此问题。谢谢你报告这个!
答案 1 :(得分:1)
实际上,错误消息与limit()
文档相结合,对已关闭的Firebase源代码有了一些了解:
如果谓词按特定顺序应用,我的赌注是limitTo*()
仍然会回落到折旧limit()
的实现。如果该订单改变了;使用不同的,可能更新且更正确的实现。
这可以解释我的问题中证明的所有不一致和问题。
很抱歉回答我自己的问题,但是只有在思考(并且正在玩!)之后我想出了这个。 已经提交了Firebase的门票,他们可能会在这里回答。