【问题标题】:How to workaround firestore basic query in my scenario如何在我的场景中解决 Firestore 基本查询
【发布时间】:2018-05-30 18:43:31
【问题描述】:

我有一个如下结构的文档列表。

Posts ->
  ->uuid_1
    -> approvedCount : 5
    -> postMsg : "Hello world 1"
    -> Timestamp : 1234567890
    -> userId : "user1"
  ->uuid_2
    -> approvedCount : 6
    -> postMsg : "Hello world 2"
    -> Timestamp : 1234567891
    -> userId : "user2"

firestore 中可能有数千个帖子,而且大小还在不断增加。

条件 -> approvedCount 在查询中过滤时必须大于 5。

现在我想每天按时间戳的升序获取 20 条记录。我不想重复,所以假设今天我按升序获取了 20 条第一条记录,明天我想获取接下来的 20 条记录,依此类推..

我尝试了类似的东西

FirebaseUtil.getFireStoreDB("Posts").whereGreaterThan("approvedCount", 5)
                .limit(20)
                .orderBy("Timestamp", Query.Direction.ASCENDING)
                .get()

但不知道我将如何每天获取下一篇文章。因为从文档中我了解到您不能使用 查询 2 个字段,否则使用时间戳和批准计数会更容易

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    要解决这个问题,您需要使用Paginate Data with Query Cursors,您会在其中找到一个非常有用的名为startAfter() 的方法,您可以在其中将documentSnapshots 对象的最后一个可见元素作为参数传递。在官方文档中,您应该使用以下代码:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    // Construct query for first 20
    Query first = rootRef.whereGreaterThan("approvedCount", 5)
                    .orderBy("Timestamp", Query.Direction.ASCENDING)
                    .limit(20);
    
    first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot documentSnapshots) {
            // Get the last visible document
            DocumentSnapshot lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1);
    
            // Construct a new query starting at this document, to get the next 20 records
            Query next = rootRef.whereGreaterThan("approvedCount", 5)
                    .orderBy("Timestamp", Query.Direction.ASCENDING)
                    .startAfter(lastVisible)
                    .limit(20);
    
            // Do what you need to do with your query
        }
    });
    

    【讨论】:

    • 好的,约翰,让我知道。干杯!
    • 我收到错误You have an inequality where filter (whereLessThan(), whereGreaterThan(), etc.) on field 'approvedCount' and so you must also have 'approvedCount' as your first orderBy() field, but your first orderBy() is currently on field 'timeStamp' instead. 我尝试了不同的组合,但结果不是我想要的。我只是想要select * from posts where approvedCount &gt; 5 orderBy Timestamp asc limit 20
    • 哦,你说得对,Firestore 中的订单非常重要。刚刚编辑了我的答案。如果您有一个具有范围比较(、>=)的过滤器,则您的第一个排序必须在同一字段上。也不要忘记使用indexes
    • 我没试过。我今晚试试。但我认为我可以拥有两个集合all_postsapproved_posts。我将使用 cron 作业编写一个 firebase 函数,该函数将从all_posts 集合中提取已批准的帖子并将其放入approved_posts,然后从all_posts 中删除该帖子。然后我可以简单地从approved_posts 查询。这会是个好主意吗?
    • 我还在学习,我需要忘记关系数据库的主体才能从 NoSql db 中获得更多信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多