【问题标题】:Cloud Firestore get collection by reference from another collectionCloud Firestore 通过引用从另一个集合中获取集合
【发布时间】:2018-12-21 18:42:14
【问题描述】:

我有一个名为 Products 的集合和另一个名为 Category 的集合。

Products 文档有一个字段 idCategory,引用类别的 ID。

我想从Products 获取类别名称等于“Soda”的所有文档。

我该怎么做?

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    我想从 Products 中获取类别名称等于“Soda”的所有文档。

    因为您没有在一个文档中包含所有数据,所以您需要查询您的数据库两次。在这种情况下,一次获取类别的 ID,即“Soda”,然后根据该 ID 获取相应的产品。这是因为 Firestore 不支持跨多个集合的查询。单个查询只能使用单个集合中文档的属性。

    为什么要查询数据库两次,当您可以查询一次并获得所需的文档时,成本也很高。为此,您需要对数据库模式进行一些更改。由于单个产品可能属于多个类别,因此您的新架构应如下所示:

    Firestore-root
        |
        --- products (collection)
              |
              --- productId (document)
                    |
                    --- productName: "Soda Water"
                    |
                    --- category: ["Soda", "Other Category"]
                    |
                    --- //Other properties
    

    要获取不属于Soda 类别的所有文档,请使用以下代码行:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    CollectionReference productsRef = rootRef.collection("products");
    Query query = productsRef.whereArrayContains("category", "Soda");
    

    编辑:您还可以保留引用而不是仅保留 id,但为此,请参阅我在此 post 中的回答。

    【讨论】:

    • 不幸的是,在这种情况下无法更改数据库:/
    • 在这种情况下,您应该查询数据库两次。但请记住,在 Firestore 中,一切都与读取次数和写入次数有关。请参阅here 更多信息。因此,您的应用将花费比需要更多的读取操作,这将花费您更多。
    • 如果这是一个愚蠢的问题,我很抱歉,但是当我使用 .collection(“Category”).document(“Soda”).collection(“Products”) 时会发生什么?
    • 您正在查找Products 子集合中的所有文档。
    【解决方案2】:

    看起来你会做一个简单的查询(Firebase Docs Reference):

    FirebaseFirestore db = FirebaseFirestore.getInstance();
    
    CollectionReference productsRef = db.collection("Products");
    
    Query query = productsRef.whereEqualTo("idCategory", "Soda");
    
    query.get()
    .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
            /// do things with response
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            /// do things with error
        });
    

    【讨论】:

    • 不可能,因为 Soda 不是 Category 的 id 属性
    • 啊!我想我误解了你的 nosql 结构。我很高兴你找到了解决方案。亚历克斯很好地澄清了你的结构。您的声明“我想从 Products 中获取类别名称等于“Soda”的所有文档。”表示“Soda”是 Product 文档的一部分,变量名称为 category。
    猜你喜欢
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    相关资源
    最近更新 更多