【问题标题】:Firestore - Merging two queries locallyFirestore - 在本地合并两个查询
【发布时间】:2018-10-11 14:26:07
【问题描述】:

由于 Firestore 中没有逻辑 OR 运算符,我试图在本地合并 2 个单独的查询。

现在我想知道如何才能保持结果的正确顺序。当我独立运行 2 个查询时,我无法对结果进行具体排序(至少不是我使用 orderBy 方法从 Firestore 获取结果的顺序)。

我的想法是将第二个查询放在第一个查询的 onSuccessListener 中。这是一个坏主意吗?

public void loadNotes(View v) {
    collectionRef.whereLessThan("priority", 2)
            .orderBy("priority")
            .get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {

                    for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                        Note note = documentSnapshot.toObject(Note.class);
                        //adding the results to a List
                    }

                    collectionRef.whereGreaterThan("priority", 2)
                            .orderBy("priority")
                            .get()
                            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                                @Override
                                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {

                                    for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                                        Note note = documentSnapshot.toObject(Note.class);
                                        //adding the results to a List
                                    }
                                }
                            });
                }
            });
}

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    要在本地合并 2 个单独的查询,我建议您使用 Tasks.whenAllSuccess() 方法。您可以使用以下代码行来实现这一点:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    Query firstQuery = rootRef...
    Query secondQuery = rootRef...
    
    Task firstTask = firstQuery.get();
    Task secondTask = secondQuery.get();
    
    Task combinedTask = Tasks.whenAllSuccess(firstTask, secondTask).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
        @Override
        public void onSuccess(List<Object> list) {
             //Do what you need to do with your list
        }
    });
    

    如您所见,当覆盖onSuccess() 方法时,结果是对象的list,其具有作为参数传递给whenAllSuccess() 方法的任务的确切顺序。

    还有另一种方法,那就是使用Tasks.continueWith() 方法。但是根据您的应用程序的用例,您可以使用eiter whenAllSuccess() 方法或continueWith() 方法。请在此处查看official documentation

    【讨论】:

    • 非常感谢!我实际上在网上找到了相同的解决方案,但如果它们是正确的,我会非常不安全,因为我发现的例子太少了。既然你命名了完全相同的方法,我就有了保险。一件事:我是一个新手,所以我对泛型有问题,但我注意到当我写Task&lt;List&lt;QuerySnapshot&gt;&gt; combinedTask而不是像Task那样声明类型时,我在OnSucess中得到一个List&lt;QuerySnapshot&gt;,而不是List&lt;Object , 这样更方便。这是声明类型的正确方法吗?
    • QuerySnapshot 类,就像 Java 中的所有其他类一样,扩展了 Object 类。类对象是类层次结构的根。每个类都有 Object 作为超类。所以QuerySnapshot 是一个对象。在这种情况下,QuerySnapshot 是相关类型,因此请随意使用List&lt;QuerySnapshot&gt;
    • 好的,但这比在onSuccess 中转换objects 更好还是没关系?
    • @fkvestak 您将总是承担与返回的元素数量相等的读取操作数。例如,如果您有 3 个查询,并且每个查询都返回 3 个文档,那么您将被收取 9 次文档读取的费用。
    • @fkvestak 我认为article 将提供更多信息。真的不是你说的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 2016-05-26
    • 2012-09-02
    • 2011-09-27
    相关资源
    最近更新 更多