首页 > 解决方案 > 使用 where 字段与替代方法的 Firebase 查询效率

问题描述

我有一个 firebase 应用程序,其中包含一个集合,其中包含在应用程序上发布的帖子,每个帖子都有一个包含帖子数据的文档。作为用户,您可以点赞帖子,并且您点赞帖子的 UID 存储在用户文档中。作为应用程序的过去,我希望能够检索用户喜欢的所有帖子。我有两种方法可以做到这一点:

第一个选项我可以使用 where 字段选项:

    static func getLikedPosts(likedIDs: [String], completion: @escaping ((_ data: [Post]) -> Void))  {
        db.collection("posts").whereField("postID", in: likedIDs).getDocuments {(querySnapshot, err) in
            if let err = err {
                print(err)
            } else {
                var listings: [Listing] = []

                for doc in querySnapshot!.documents {
                   
                    // ...
                    let post = Post()
                    posts.append(post)
                }

                completion(posts)
            }
        }
    }

第二个选项是我有一个功能来获得一个帖子:

    static func getPost(listingID: String, completion: @escaping ((_ data: Post) -> Void)) {
        db.collection("posts").document(postID).getDocument { (doc, err) in
            if let err = err {
                print(err)
            } else {
                if let doc = doc, doc.exists {
                    
                    
                    if let data = doc.data() {
                        
                        // ...
                        let post = Post()
                        completion(post)
                    }

                }
            }
        }
    }

然后为了获得所有喜欢的帖子,我使用以下功能:

    static func getLikedPosts(likedIDs: [String], completion: @escaping ((_ data: [Post]) -> Void)) {
        var posts = [Post]()
        for id in likedIDs {
            getPost(postID: id) { (post) in

                listings.append(post)
                
                if posts.count == likedIDs.count {
                    completion(posts)
                }
            }
        }
    }

我的问题是,如果在大量帖子上更高效/可扩展,或者是否有更好的选择,这两个选项中的哪一个?我想使用 where 字段的时间复杂度会更高,但不确定 firebase 如何管理这些查询。

标签: swiftfirebasegoogle-cloud-firestore

解决方案


这两种方法之间不会有显着的性能差异。我个人更喜欢通过 ID 获取每个帖子,因为这意味着我不会处理in查询的 10 个值的限制。但正如所说:这只是个人喜好。

唯一更好的选择是,如果您可以使用相等查询 ( ==) 或范围查询 ( >, <, >=, <=) 获得用户的收藏夹,但我没有看到此用例的选项。

另一种选择是将用户收藏的帖子存储在该用户的单独(子)集合中,这样您就可以简单地阅读整个集合。这意味着您将在编写帖子时复制帖子,并在更新帖子时将其与数据保持同步,但作为交换,您将获得更快、更具可扩展性的读取行为。

这是使用 NoSQL 数据库时的常见权衡:并且是经典空间与时间权衡的实现。


推荐阅读