gpt4 book ai didi

android - Firestore 查询 StartAt(DocumentReference) 没有给出正确的结果

转载 作者:行者123 更新时间:2023-12-02 13:28:44 24 4
gpt4 key购买 nike

在我的 firestore 数据库中,有 12+ 个文档。我通过调用以下函数 on button click 正确获取了前 3 个文档.但是在 secondclick ,尽管正确传递了 documentReference,但它没有检索任何数据。querySnapshot 大小即将变为 0。可能是什么问题。
下面给出的是声明

private val db: FirebaseFirestore = FirebaseFirestore.getInstance()
private val colRef: CollectionReference = db.collection("Notebook")
private var lastResult: DocumentReference? = null
private lateinit var query: Query
以下是 onButtonClick代码 :
private fun loadNoteNew() {
@Suppress("SENSELESS_COMPARISON", "LiftReturnOrAssignment")
if (lastResult == null) {
query = colRef.orderBy("priority")
.limit(3)
} else {
Log.i(TAG, "Start ${lastResult!!.id}")
query = colRef.orderBy("priority")
.startAfter(lastResult)
.limit(3)
}

Log.i(TAG, "before get")
query.get()
.addOnSuccessListener { querySnapshot ->
var data = ""
Log.i(TAG, "querySnapshot Size : ${querySnapshot.size()}")
if (lastResult != null) {
Log.i(TAG, "querySnapshot ID : ${lastResult!!.id}")
}


for (snapshot in querySnapshot) {
val note = snapshot.toObject(Note::class.java)
note.id = snapshot.id

val title = note.title
val desc = note.description
val priority = note.priority
data += "${note.id} \nTitle =$title \nDescription = $desc\nPriority : $priority\n\n"
}
if (querySnapshot.size() > 0) {
data += "---------------\n\n"
textView_loadData.append(data)
lastResult = querySnapshot.documents[querySnapshot.size() - 1].reference
Log.i(TAG, lastResult!!.id)
}
}
}
下面给出的是第一次点击的 logcat
I/FireStoreExample: before get
I/FireStoreExample: querySnapshot Size : 3
I/FireStoreExample: P9hIw4Ai7w4IHP6H3ew3
下面给出的是第二次点击的logcat
I/FireStoreExample: Start P9hIw4Ai7w4IHP6H3ew3
I/FireStoreExample: before get
I/FireStoreExample: querySnapshot Size : 0
I/FireStoreExample: querySnapshot ID : P9hIw4Ai7w4IHP6H3ew3
请帮我找出我在哪里弄错了。
谢谢

最佳答案

第二个查询结果是空的,因为对使用 的查询分页的语义有误解。开始于 开始之后 方法。
假设 Notebook 集合包含 N 个文档。当您进行第一个查询时,您要求的是按优先级字段排序的前 3 个文档,因此查询返回文档 1..3。然后在第二次单击时,您期望查询返回接下来的 3 个结果,因此您确实期望文档 4..6。这里的关键点是 开始于 开始之后 根据有序字段的值而不是根据检索到的最后一个文档进行分页。总体上 startAt 和 startAfter 的语义大致如下。
orderby(X).startAt(Y) => 返回 X 字段大于等于 Y 的文档
orderby(X).startAfter(Y) => 返回 X 字段严格大于 Y 的文档
考虑到这一点,让我们检查一下当您进行第二个查询时代码实际上在做什么:

// At the end of the first query...
lastResult = querySnapshot.documents[querySnapshot.size() - 1].reference

// Second query
query = colRef.orderBy("priority")
.startAfter(lastResult)
.limit(3)
在上面的代码中,您要求“优先级”字段大于文档引用“P9hIw4Ai7w4IHP6H3ew3”的文档,并且确实没有大于该值的文档,因此结果集为空。这里是 api reference对彼此而言。
还有一点需要注意。因为这些方法过滤字段值,所以光标的位置可能不明确。例如,如果您有 4 个优先级为 3 的文档,并且如果您设置 startAfter(3),则已经检索了前三个文档。你会丢失一份文件。同样,如果 startAt(3)你会得到同样的三个文件。 documentation 中也指出了这一点。 .总而言之,您有几个选项可以使这项工作按预期进行:
在另一个字段中添加另一个 orderby,以便通过组合唯一标识文档,从而防止任何光标歧义并能够使用 开始之后 有保证。下一个 fragment 基于文档示例和您的代码构建。
// first query
query = colRef.orderBy("priority")
.orderBy("AnotherField")
.limit(3)
// Save last document
lastResult = querySnapshot.documents[querySnapshot.size() - 1]

// Second and next queries
query = colRef.orderBy("priority")
.orderBy("AnotherField")
.startAfter(lastResult)
.limit(3)
最后请记住,如果文档不多并延迟优化直到它们成为性能问题,则仅查询所有文档可能会更简单。

关于android - Firestore 查询 StartAt(DocumentReference) 没有给出正确的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62617902/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com