如何在 Google Firestore 中进行分页?
How to do pagination in Google Firestore?
我有这个列表:a b c d e f g h i j
。我想从所选项目周围的列表中获取 3 个项目。如果我选择了e
,结果列表应该是d e f
,如果我选择了f
,结果应该是e f g
等等。
我做了这个例子:
console.clear()
var pag = dbFirestore.collection("pagination")
pag.doc("a").set({parent:"vowels"})
pag.doc("e").set({parent:"vowels"})
pag.doc("i").set({parent:"vowels"})
pag.doc("o").set({parent:"vowels"})
pag.doc("u").set({parent:"vowels"})
pag.doc("y").set({parent:"vowels"})
pag.doc("b").set({parent:"consonants"})
pag.doc("c").set({parent:"consonants"})
pag.doc("d").set({parent:"consonants"})
pag.doc("f").set({parent:"consonants"})
pag.doc("g").set({parent:"consonants"})
pag.doc("h").set({parent:"consonants"})
pag.doc("j").set({parent:"consonants"})
pag.doc("k").set({parent:"consonants"})
pag.doc("l").set({parent:"consonants"})
pag.doc("m").set({parent:"consonants"})
pag.doc("n").set({parent:"consonants"})
pag.doc("p").set({parent:"consonants"})
pag.doc("q").set({parent:"consonants"})
pag.doc("r").set({parent:"consonants"})
pag.doc("s").set({parent:"consonants"})
pag.doc("t").set({parent:"consonants"})
pag.doc("v").set({parent:"consonants"})
pag.doc("w").set({parent:"consonants"})
pag.doc("x").set({parent:"consonants"})
var siblings = ref => {
var out = []
return pag.orderBy("parent").endAt(ref).limit(3).get().then(snap=>{
snap.forEach(doc=>out.push(doc.id))
return
}).then(()=>{
return pag.orderBy("parent").startAfter(ref).limit(2).get().then(snap=>{
snap.forEach(doc=>out.push(doc.id))
return out
})
})
}
siblings(pag.doc("m")).then(out=>{
console.log(out)
}).catch(e=>console.error(e))
在 out
中使用 sibling("m").then(out=>console.log(out))
我应该有 k l m n p
,他们都有 parent:"consonants"
,第一个查询的 k l m
与 n p
来自第二个查询,但我还有别的东西。
问题出在您形成查询的方式上。 startAt
、endAt
等对您传递给 orderBy
的字段进行操作。所以如果你做 .orderBy("parent").startAt("foo")
那就是说 "order all documents by the value of doc.parent, starting where doc.parent == foo".
因此您必须在此处进行一些更改。首先,如果将字母的值存储在文档中,查询起来会更容易,因此您的文档可能如下所示:
{
"val": "a",
"parent": "vowels"
}
然后您可以执行此查询:
/**
* ex: siblingsOf("a", "vowels");
*/
function siblingsOf(letter, parent) {
var out = [];
// Starting at the letter, read "up" three documents
var threeBefore = pag.where("parent", "==", parent)
.orderBy("val", "desc").startAt(letter).limit(3);
// Starting after the letter, read "down" three documents
var twoAfter = pag.where("parent", "==", parent)
.orderBy("val").startAfter(letter).limit(2);
return threeBefore.get().then(snap => {
// Add to beginning of array
snap.forEach(doc => out.unshift(doc.data()));
}).then(() => {
return twoAfter.get().then(snap => {
// Add to end of array
snap.forEach(doc => out.push(doc.data()));
return out;
});
});
}
所以如果我这样做 siblingsOf("j", "consonants")
我会得到 "g", "h", "j", "k", "l"
的文件。
firebase 在 Pagination & Query 上有文档。我们必须使用 startAt() 或 startAfter() 方法来定义查询的起点。同样,使用 endAt() 或 endBefore() 方法定义查询结果的终点。
我有这个列表:a b c d e f g h i j
。我想从所选项目周围的列表中获取 3 个项目。如果我选择了e
,结果列表应该是d e f
,如果我选择了f
,结果应该是e f g
等等。
我做了这个例子:
console.clear()
var pag = dbFirestore.collection("pagination")
pag.doc("a").set({parent:"vowels"})
pag.doc("e").set({parent:"vowels"})
pag.doc("i").set({parent:"vowels"})
pag.doc("o").set({parent:"vowels"})
pag.doc("u").set({parent:"vowels"})
pag.doc("y").set({parent:"vowels"})
pag.doc("b").set({parent:"consonants"})
pag.doc("c").set({parent:"consonants"})
pag.doc("d").set({parent:"consonants"})
pag.doc("f").set({parent:"consonants"})
pag.doc("g").set({parent:"consonants"})
pag.doc("h").set({parent:"consonants"})
pag.doc("j").set({parent:"consonants"})
pag.doc("k").set({parent:"consonants"})
pag.doc("l").set({parent:"consonants"})
pag.doc("m").set({parent:"consonants"})
pag.doc("n").set({parent:"consonants"})
pag.doc("p").set({parent:"consonants"})
pag.doc("q").set({parent:"consonants"})
pag.doc("r").set({parent:"consonants"})
pag.doc("s").set({parent:"consonants"})
pag.doc("t").set({parent:"consonants"})
pag.doc("v").set({parent:"consonants"})
pag.doc("w").set({parent:"consonants"})
pag.doc("x").set({parent:"consonants"})
var siblings = ref => {
var out = []
return pag.orderBy("parent").endAt(ref).limit(3).get().then(snap=>{
snap.forEach(doc=>out.push(doc.id))
return
}).then(()=>{
return pag.orderBy("parent").startAfter(ref).limit(2).get().then(snap=>{
snap.forEach(doc=>out.push(doc.id))
return out
})
})
}
siblings(pag.doc("m")).then(out=>{
console.log(out)
}).catch(e=>console.error(e))
在 out
中使用 sibling("m").then(out=>console.log(out))
我应该有 k l m n p
,他们都有 parent:"consonants"
,第一个查询的 k l m
与 n p
来自第二个查询,但我还有别的东西。
问题出在您形成查询的方式上。 startAt
、endAt
等对您传递给 orderBy
的字段进行操作。所以如果你做 .orderBy("parent").startAt("foo")
那就是说 "order all documents by the value of doc.parent, starting where doc.parent == foo".
因此您必须在此处进行一些更改。首先,如果将字母的值存储在文档中,查询起来会更容易,因此您的文档可能如下所示:
{
"val": "a",
"parent": "vowels"
}
然后您可以执行此查询:
/**
* ex: siblingsOf("a", "vowels");
*/
function siblingsOf(letter, parent) {
var out = [];
// Starting at the letter, read "up" three documents
var threeBefore = pag.where("parent", "==", parent)
.orderBy("val", "desc").startAt(letter).limit(3);
// Starting after the letter, read "down" three documents
var twoAfter = pag.where("parent", "==", parent)
.orderBy("val").startAfter(letter).limit(2);
return threeBefore.get().then(snap => {
// Add to beginning of array
snap.forEach(doc => out.unshift(doc.data()));
}).then(() => {
return twoAfter.get().then(snap => {
// Add to end of array
snap.forEach(doc => out.push(doc.data()));
return out;
});
});
}
所以如果我这样做 siblingsOf("j", "consonants")
我会得到 "g", "h", "j", "k", "l"
的文件。
firebase 在 Pagination & Query 上有文档。我们必须使用 startAt() 或 startAfter() 方法来定义查询的起点。同样,使用 endAt() 或 endBefore() 方法定义查询结果的终点。