代码之家  ›  专栏  ›  技术社区  ›  user5489654

如何高效地在Firebase Cloud Firestore中执行多次读取?

  •  2
  • user5489654  · 技术社区  · 8 年前

    我在Firebase的Cloud Firestore数据库中有一个集合,其子集合如下:

    myCollection
        doc1
            statistics
                doc1
                doc2
                doc3
        doc2
            statistics
                doc1
                doc2
        doc3
            statistics
                doc1
                doc2
                doc3
                doc4
        doc4
            statistics
    

    等等

    例如,根据查询,我可能从集合中提取doc1、doc2和doc4。现在,对于每一个,我需要查询它们各自的子集合以获取相关统计信息。

    到目前为止,我在AngularJS应用程序中的解决方案是:

    /**
     * Gets aggregate views for queried docs.
     * @param {![firebase.firestore.DocumentSnapshot]} docs - the queried documents 
     */
    $scope.getTotalViews = (docs) => {
        let promises = [];
        docs.forEach(doc => {
            promises.push($scope.getTotalDocumentViews(doc.id));
        });
        $q.all(promises).then(totalViewsArray => {
            // TODO: Sum the array to get aggregate views for queried documents
            // Only outputs some of the time
            console.log(totalViewsArray);
        });
    };
    
    /**
     * Gets all view statistics from a given document's subcollection.
     */
    $scope.getTotalDocumentViews = (id) => {
        let deferred = $q.defer();
        firebase.firestore().collection("myCollection").doc(id).collection("statistics").where("type", "==", "view").get().then(snapshot => {
            deferred.resolve(snapshot.size);
        });
        return deferred.promise;
    };
    

    我遇到的问题是,由于myCollection上的查询可能返回许多文档,因此循环遍历所有这些文档并查询其子集合似乎效率极低。不仅如此,尽管上述代码在某些时候确实成功,但在很多时候它会抛出错误:

    Uncaught (in promise) Error: transaction closed
    

    我还尝试在一个事务中执行多个子集合查询,但效果不太好,因为我不是只检索一个文档,而是从子集合中查询可能有数百个文档。

    如何有效地查询一组多个文档的子集合?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Frank van Puffelen    8 年前

    我认为这同样适用于大多数其他NoSQL数据库(当然也适用于Firebase实时数据库):如果您希望能够有效地从数据库中获取某个数据的计数,您应该将该计数存储为属性,并不断更新(在本例中)视图。试图读取数百个文档来确定它们的数量是不会扩大的。

    因此,考虑添加一个 view_count 属性,并增加该属性(可能使用 transaction )记录视图时。

    推荐文章