Firebase JS:startAt,orderByChild和limitToLast [英] Firebase js: startAt, orderByChild and limitToLast
问题描述
我有以下查询以获取自上次提取以来的最新16篇文章:
I have the following query to get the newest 16 articles since the last fetch:
db.ref("articles).startAt(null, "last_fetched_key").orderByChild("published").limitToLast(16);
所以它应该从我写的最后一篇文章开始,然后按已发布"子键排序,然后将结果限制为16.
So it should start at the last article I have, then order those by the child key "published", then limit those results to 16.
只要我不执行orderByChild("published"),它就可以正常工作,但是如果我这样做,我总是可以获得16个项目?
It works as long as I don't do orderByChild("published") but if I do, I always get 16 items?
注意:我在nodejs(firebase-admin 5.1.0)和浏览器(firebase-sdk 4.2.0)上都看到了此行为
Note: I see this behavior on both nodejs (firebase-admin 5.1.0) and browser (firebase-sdk 4.2.0)
示例:(有关数据示例,请参见下文)
Example: (see below for data example)
function countObj(obj) { var c=0; for (var k in obj) { c++; } return c; }
function getLastKey(obj) { var lk=null; for (var k in obj) { lk = k; } return lk; }
firebase.database().ref("articles/-KnLhC7S0wtNV17R-w2I")
.orderByChild("published")
.limitToLast(4) // limit 4,
.once("value", function(snap) {
var data = snap.val();
console.log("#1 Results: "+ countObj(data.val())); // Results: 4
var lastKey = getLastKey(data);
// With .orderByChild("published")
// Should return 1 result because articles contains 4, we pass the 4th key to startAt()
firebase.database().ref("articles/-KnLhC7S0wtNV17R-w2I")
.startAt(null, lastKey) // use startAt
.orderByChild("published")
.limitToLast(4)
.once("value", function(snap) {
var data = snap.val();
console.log("#2 Results: "+ countObj(data.val())); // Results: 4
});
// Without .orderByChild("published")
// Returns 1 result because articles contains 4, we pass the 4th key to startAt()
firebase.database().ref("articles/-KnLhC7S0wtNV17R-w2I")
.startAt(null, lastKey) // use startAt
.limitToLast(4)
.once("value", function(snap) {
var data = snap.val();
console.log("#3 Results: "+ countObj(data.val())); // Results: 1
});
});
数据:
{
"articles" : {
"-KnLhC7S0wtNV17R-w2I" : {
"1498230632000-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : {
"published" : 1498230632000
},
"1498230632001-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : {
"published": 1000
},
"1498230632002-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : {
"published": 900
},
"1498230632003-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : {
"published": 1100
},
}
}
}
推荐答案
您似乎误解了 startAt()
的参数是如何工作的.这里有三个步骤:
You seem to misunderstand how the parameters for startAt()
work. There are three steps here:
- 首先,按照查询的指示对数据进行排序.如果您未指定任何排序,则数据将按优先级排序(对于您的情况下的所有数据都是相同的)
- 查询然后找到第一个子项,其排序的值与您指定为第一个参数的子项匹配.
- 然后查询执行(可选)秒,并删除键之前的所有项目.
因此,在查询中,如果要在 1498230632003 ...
之后的下4个项目:
So in your query, if you want the next 4 items after 1498230632003...
:
ref
.orderByChild("published")
.startAt(1100, "1498230632003-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7")
.once("value", function(snap) {
console.log("#2 Results: "+snap.numChildren()); // Results: 2
snap.forEach(function(child) {
console.log(child.key); // 1498230632003..., 1498230632000...
});
});
如果要根据关键字确定从哪里开始查询结果,应使用 orderByKey()
:
If you want to determine where to start the query results based on the key, you should use orderByKey()
:
ref
.orderByKey()
.startAt("1498230632003-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7")
.once("value", function(snap) {
console.log("#2 Results: "+snap.numChildren()); // Results: 1
snap.forEach(function(child) {
console.log(child.key); // 1498230632003...
});
});
我不确定,但是似乎您正在尝试获取要对属性进行排序并对键进行过滤的查询.在Firebase数据库查询模型中,这是不可能的.有关您的选择,请参见 http://stackoverflow.com/questions/26700924/query-base-on-multiple-where-clauses-in-firebase
I'm not completely certain, but it seems like you're trying to get a query to order on a property and filter on the key too. This is not possible within the Firebase Database query model. For your options, see http://stackoverflow.com/questions/26700924/query-based-on-multiple-where-clauses-in-firebase
我要测试的jsbin: https://jsbin.com/xuwaxaq/edit?js,控制台
My jsbin for testing: https://jsbin.com/xuwaxaq/edit?js,console
您的代码中的一些代码片段很难理解.我建议用我更惯用的变体替换它们:
A few snippets from your code are hard to understand. I recommend replacing them with my more idiomatic variants:
countObj(data.val())
与以下相同:
snap.numChildren()
并且:
var lastKey = getLastKey(data);
与以下相同:
var lastKey;
snap.forEach(function(child) { lastKey = child.key; });
这篇关于Firebase JS:startAt,orderByChild和limitToLast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!