本文介绍了类似SQL的Firestore中的联接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Cloud Firestore中有一个名为 creditcards 的集合和一个名为 ownedcreditcards 的集合.我想执行一个查询,在该查询中我加入两个集合以仅找到 creditcards -集合中存在的信用卡,而不是 ownedcreditcards 中存在的信用卡.据我了解,Firestore中不存在像JOINS这样的SQL,您必须在多个查询中检索数据.我试图在两个集合上调用 getAll()-函数(检索所有文档),将数据临时存储在两个 ArrayLists 中,然后比较两个互相列出.但是我尝试将数据存储在 ArrayList 中的尝试失败,因为当我尝试 LOG 时它返回空.
如何将两个集合中的数据存储在 ArrayList 中,或者有更简单的方法呢?

I have a collection called creditcards and a collection called ownedcreditcards in Cloud Firestore. I want to perform a query where I JOIN the two collections to find only the creditcards that exists in the creditcards-collection, and not in the ownedcreditcards. From my understanding SQL like JOINS does not exist in Firestore, and you have to retrieve the data in multiple queries. I am trying to call the getAll()-functions (which retrieves all the documents) on both my collections, temporarily store the data in two ArrayLists, and then compare the two lists with each other. But my attempts of storing the data in an ArrayList has been unsuccessful, as it returns empty when I try to LOG it.
How can I store the data from both my collections in an ArrayList, or is there an easier way of doing this?

信用卡收藏,其中包含以下字段:

creditcards-collection with the following fields:

  • id
  • 名称
  • 提供者

拥有的信用卡收藏集,其中包含以下字段:

ownedcreditcards-collection with the following fields:

  • id
  • 心碎
  • 信用卡名
  • 昵称
  • 用户名

我的 Activity Store 类的代码在 usercreditcard creditcard 上大致相同.以下是 usercreditcard 的代码.

The code for my Activityand Store-classes are more or less identical for both usercreditcard and creditcard. Below is the code for the usercreditcard.

UserCreditCardActivity.kt

val arrayList = ArrayList<Any>()

    private fun retrieveCards() {
    val userCreditcard = UserCardStore()
    userCreditcard.getAll(object : Callback<UserCardModel> {
        override fun onCallback(list: List<UserCardModel>) {
            for (card in list) {
                adapter.add(UserCardItem(card)) //this works
                arrayList.add(card) //this doesnt work as when I print the list it returns empty
            }
        }
    })
}

UserCardStore.kt

    override fun getAll(myCallback: Callback<UserCardModel>) {
    auth = FirebaseAuth.getInstance()
    documentdata.whereIn("userid", listOf(auth.uid))
       .get().addOnCompleteListener { task ->
        if (task.isSuccessful) {
            val list = ArrayList<UserCardModel>()
            for (document in task.result!!) {
                val usercard = document.toObject(UserCardModel::class.java)
                list.add(usercard)
            }
            myCallback.onCallback(list)
        }
    }
}

推荐答案

是的,正确的是,"JOIN"Cloud Firestore 不支持类型操作.Firestore查询一次只能从单个集合中获取文档.如果需要从两个集合中获取数据并将结果添加到列表中,则必须执行两个不同的查询.

Yes, that's correct, a "JOIN" type operation is not supported by Cloud Firestore. A Firestore query can only get documents from a single collection at a time. If you need to get data from both collections and add the results to a list, you'll have to perform two different queries.

解决此问题的关键是仅在第一个查询完成时才尝试获取第二个查询的结果.在代码中,这些查询应如下所示:

The key to solving this problem is to attempt to get the results of the second query only when the first query completes. In code, these queries should look like this:

creditcardsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<UserCardModel> userCardList = new ArrayList<>();
            for (QueryDocumentSnapshot document : task.getResult()) {
                userCardList.add(document.toObject(UserCardModel.class));

                ownedcreditcardsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            for (QueryDocumentSnapshot doc : task.getResult()) {
                                userCardList.add(doc.toObject(UserCardModel.class));
                            }

                            //Do what you need to do with the list
                        } else {
                            Log.d(TAG, "Error getting documents: ", task.getException());
                        }
                    }
                });
            }
        } else {
            Log.d(TAG, "Error getting documents: ", task.getException());
        }
    }
});

但是,由于您总是阅读两个集合的内容,因此这种方法可能会被认为有点昂贵.您可能采取的另一种方法是引入第三个集合,该集合具有已经加入"的数据.来自两个收藏.这种做法称为非规范化,是Firebase的常见做法.为了更好地理解,我建议您观看以下视频,使用Firebase数据库进行反规范化是正常的.适用于Firebase实时数据库,但相同的规则也适用于Cloud Firestore.

However, this approach might be considered a little bit expensive since you always read the content of both collections. A possible alternative you have is to introduce a third collection with data already "joined" from both collections. This practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database. It's for Firebase Realtime Database, but the same rules apply to Cloud Firestore.

这篇关于类似SQL的Firestore中的联接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 11:00