Firestore startAfter上一个快照不起作用,如果两个或多个文档具有相同的字段值



我有一个名为"test"的集合,它有多个文档。每个文档都有一个唯一的名称和一个数字字段。我已经使用查询游标实现了分页。获取初始文档的查询如下:

let lastDocument={};
ref.collection("test").orderBy('number', 'desc').limit(3).get()
.then(snapshot => {
lastDocument = snapshot.docs[snapshot.docs.length-1];
})
.catch(err => {
console.log("Error getting documents", err);
});

在得到最后一个文档后,我将其分页如下:

ref.collection("test").orderBy('number', 'desc').startAfter(lastDocument).limit(3); //lastDocument has the last document of the snapshot that was retrieved.

在我的集合中,如果有两个或多个文档的字段"number"值相同,那么我不会在查询结果中得到该文档。然而,如果我更改字段"number"的值,以便使所有文档都是唯一的,我会正确地分批(根据限制条款)获得所有结果。

文档中也提到,如果多个字段具有相同的填充值,则查询将不起作用https://firebase.google.com/docs/firestore/query-data/query-cursors#paginate_a_query

我应该如何修改查询,以便在结果中获得所有文档,即使两个或多个文档对orderBy中使用的字段具有相同的值?

我正在使用:

"react-native-firebase": "^5.5.6", "react-native": "^0.59.8", "firebase": "^6.6.1",

更新:我已经在JSbin上测试了查询,它返回正确的后果当我在具有react原生firebase库。我已经认识到的模式远如下:比方说,有如下文件{id:a,num:1},{id:b,num:2},{id:c,num:2},{id:d,num:2},{id:e,num:3},{id:f,num:4}然后,如果我用orderBy('num','desc')和limit查询第一个集合作为2,我得到[a,b]。现在,如果我使用startAfter last进行查询文档为'b',限制为2,则它将跳过所有文档在b之后,它们具有与b相同的num(即2)。所以,它会跳过doc[c,d]并返回我[e,f]。这在jsbin上运行良好,但在react上不起作用native使用react native firebase库。

请在下面的react native上找到代码的确切输出:

"得到所有结果">

"wbXwyLJheRfYXWlY46j=>{\"索引":2,\"编号":2}">

"kGC5cYPN1nKnZCcAb9oQ=>{\"索引\":6,\"编号\":2}">

"8EK8IWCDQPJ5s2n8PIQ=>{\"索引\":4,\"编号\":2}">

"mr7MdAygvuheF6AUtWma=>{\"索引\":1,\"编号\":2}">

"RCO5SvNn4fdoE49OKrIV=>{\"索引\":3,\"编号\":1}">

"CvVG7VP1hXTtcfdUaeNl=>{\"索引\":5,\"编号\":1}">

"获取第一页">

"wbXwyLJheRfYXWlY46j=>{\"索引":2,\"编号":2}">

"kGC5cYPN1nKnZCcAb9oQ=>{\"索引\":6,\"编号\":2}">

"获得第二页">

"mr7MdAygvuheF6AUtWma=>{\"索引\":1,\"编号\":2}">

"RCO5SvNn4fdoE49OKrIV=>{\"索引\":3,\"编号\":1}">

请注意,它已跳过:"8EK8IWCDQPJ5s2n8PIQ=>{\"index \":4,\"number \":2}">

在react原生firebase库中又遇到了一个问题:如果文档中有如下地图结构:

{
subscribedUsers:{
+1656666:true,
+1657878:false,
+1677676:true
}
}

现在,如果我发出如下查询:

db.collection("ownerUsers").其中(subscribedUsers.${phonenumber},'===',true).limit(3).get();

查询返回3个结果。现在,如果我尝试使用下面这样的startAfter子句来获得接下来的3个结果,它可以很好地使用firebase,但不能使用react原生firebase库:

db.collection("ownerUsers")where(subscribedUsers.${phonenumber},'==',true).startAfter(last).limit(3).get()

然后我得到以下错误:

[Info] 11-10 21:38:42.631 21908 21967 I ReactNativeJS: 'Error getting documents', { [Error: Firestore: Client specified an invalid argument. (firestore/invalid-argument).]

这是react-native-firebase库中的一个错误。查看Github上的问题,继续关注。该问题现在被标记为已修复,此修复将包含在下一个版本中(>5.5.6)


下面的旧答案。。。


传递到startAfter中的文档需要包含Firestore所需的所有内容,以确定下一步的起点。如果筛选的字段在集合中不是唯一的,则DocumentSnapshot还需要包含文档的ID。如果您的查询显示的是符合条件的第一个或第二个文档,而不是您要查找的文档之后的文档,则很可能是因为lastDocument中缺少ID。


更新后,我尝试用以下代码重现问题:

var db = firebase.firestore();
var ref = db.collection("58783480").orderBy('number', 'desc');
ref.get().then(function(snapshot) {
console.log("Got all results");
snapshot.forEach(function(doc) {
console.log(doc.id+' => '+JSON.stringify(doc.data()));
});  
var last;
ref.limit(2).get().then(function(snapshot) {
console.log("Got first page");
snapshot.forEach(function(doc) {
console.log(doc.id+' => '+JSON.stringify(doc.data()));
last = doc;
});
ref.startAfter(last).limit(2).get().then(function(snapshot) {
console.log("Got second page");
snapshot.forEach(function(doc) {
console.log(doc.id+' => '+JSON.stringify(doc.data()));
last = doc;
});
});
})
});

此处的示例

但输出与我所期望的完全匹配:

获得所有结果

wbXwyLJheRfYXWlY46j=>{"索引":2,"数字":2}

kGC5cYPN1nKnZCcAb9oQ=>{"索引":6,"数字":2}

8EK8IWCDQPJ5s2n8PIQ=>{"索引":4,"数字":2}

mr7MdAygvuheF6AUtWma=>{"索引":1,"数字":1}

RCO5SvNn4fdoE49OKrIV=>{"索引":3,"数字":1}

CvVG7VP1hXTtcfdUaeNl=>{"索引":5,"数字":1}

获得第一页

wbXwyLJheRfYXWlY46j=>{"索引":2,"数字":2}

kGC5cYPN1nKnZCcAb9oQ=>{"索引":6,"数字":2}

获得第二页

8EK8IWCDQPJ5s2n8PIQ=>{"索引":4,"数字":2}

mr7MdAygvuheF6AUtWma=>{"索引":1,"数字":1}

相关内容

  • 没有找到相关文章

最新更新