【问题标题】:OrderBy and StartAt with two different fields firestoreOrderBy 和 StartAt 具有两个不同的字段 firestore
【发布时间】:2020-12-25 08:25:12
【问题描述】:

在我的应用程序中,我有一个字段值为 threadCommentCount 的 cmets。我想使用 orderBy threadCommentCount 降序对 cme​​ts 进行排序,然后使用 startAfter(lastThreadCommentCount) 继续分页。问题是当 threadCommentCount 为 0(其中很多)时,它每次都会返回相同的数据,因为它每次都从 0 开始。这是查询:

popularCommentsQuery = db
                        .collection('comments')
                        .where('postId', '==', postId)
                        .orderBy('threadCommentCount', 'desc')
                        .startAfter(startAfter)
                        .limit(15)
                        .get()

一旦threadComment计数为0,这将每次返回相同的cmets。我无法发送最后一个文档快照,因为我使用云函数并且我不想在get查询参数中发送documentSnapshot。我真的不在乎在 threadCommentCount 为 0 之后如何对 cme​​ts 进行排序,我只需要不得到任何重复项。任何帮助都很棒!

【问题讨论】:

    标签: node.js google-cloud-firestore pagination


    【解决方案1】:

    所有 Firestore 查询都有一个 implicit orderBy("__name__", direction) 来解决文档之间的任何联系,这些文档对于其他名为 orderBy 的字段具有相同的值。这使得最终的排序顺序稳定。但它也使您能够将另一个参数传递给 startAfter 以提供您希望用于分页目的的锚文档的文档 ID。

    .startAfter(lastThreadCommentCount, lastDocumentId)
    

    在这两个值之间,您应该能够唯一标识结果集中的文档以开始下一页。

    【讨论】:

    • 指定的游标值过多。指定的值必须与查询的 orderBy() 约束相匹配。我是否必须添加另一个 orderBy,如果需要,在哪里?如果threadCommentCount相同,我想按threadComment计数然后按commentId排序。
    • 当然,尝试在第一个之后的 __name__ 上显式添加 orderBy。
    • 所以它看起来像这样? popularCommentsQuery = db .collection('cmets') .where('postId', '==', postId) .orderBy('threadCommentCount', 'desc') .orderBy('commentId', 'desc') .startAfter(startAfter , lastCommentId) .limit(15) 还是我在第二个 orderBy 字段中直接添加“__ name __”?
    • Nvm,我脑子里突然冒出一个想法,我可以将 commentId 传递给后端,然后从那里获取快照以传递给 startAfter。谢谢!
    【解决方案2】:

    所以,我尝试使用 Firestore 中的两个不同字段(时间、键)的 OrderBy 和 StartAfter 来在 flastList 中建立分页。

    关键是我们可以通过文档快照来定义查询游标[reference]

    这是我设法做到的。

    步骤1:使用where() [reference]获取文档ID(由firebase自动生成)

    const docRef = firestore().collection('shots').where('key','==','custom_key')
    const fbDocIdGeneratedByFirebase= await docRef.get().docs[0].id;
    

    第 2 步:使用 firebase 生成的文档 ID 获取文档快照(我们在第一步中获得)

    const docRef2= firestore().collection('shots').doc(fbDocIdGeneratedByFirebase)
    const snapshot = await docRef2.get();
    

    第三步:将第二步得到的snapshot传给startAfter(),让光标指向[reference] p>

     let additionalQuery =  firestore().collection('shots')
             .orderBy("time", "desc")
             .startAfter(snapshot)
             .limit(this.state.limit)      
     let documentSnapshots = await additionalQuery.get(); // you know what to do next
    ...    
    

    您能改进解决方案吗?

    【讨论】:

      猜你喜欢
      • 2020-10-10
      • 2019-06-15
      • 2021-07-07
      • 1970-01-01
      • 2020-11-21
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多