首页 > 解决方案 > 使用 whereArrayContains 搜索的效率

问题描述

我很好奇使用此代码在集合中搜索文档的效率。随着集合中文档数量的增长和数组中项目数量的增长,这种搜索是否会变得非常低效?有没有更好的方法来做到这一点,或者我可以对数据库进行架构更改以更好地优化它?有没有什么地方可以找到firestore文档的这些函数的时间复杂度?

Query query = db.collection("groups").whereArrayContains("members", userid);


替代解决方案

我最初想尝试将组 ID 存储在用户下,以便仅获取该当前用户的组,但遇到了问题并且从未找到使用多个 ID 设置 FireStoreRecyclerOptions 进行查询的解决方案。

例子:

for(String groupid : list) {
    Query query = db.collection("test-groups").document(groupid);

    FirestoreRecyclerOptions<GroupResponse> response = new FirestoreRecyclerOptions.Builder<GroupResponse>()
            .setQuery(query, GroupResponse.class)
            .build();
}

有没有办法将多个查询添加到FirestoreRecyclerOptions

标签: javaandroidfirebasegoogle-cloud-firestorefirebaseui

解决方案


随着集合中文档数量的增长和数组中项目数量的增长,这种搜索是否会变得非常低效?

问题不在于搜索将变得非常低效,问题在于文档有限制。因此,在您可以将多少数据放入文档时存在一些限制。根据有关使用和限制的官方文档:

文档的最大大小:1 MiB(1,048,576 字节)

如您所见,单个文档中的数据总量限制为 1 MiB。当我们谈论存储文本时,您可以存储几乎所有内容,但是随着您的数组变大,请注意此限制。

如果您在数组中存储大量数据并且这些数组应该由大量用户更新,那么您需要注意另一个限制。因此,每个文档每秒只能写入 1 次。因此,如果您遇到很多用户都试图一次将数据写入/更新到相同文档的情况,您可能会开始看到其中一些写入失败。所以,也要小心这个限制。

您可能已经注意到,Cloud Firestore 中的查询非常快,这是因为 Firestore 会自动为您文档中的任何字段创建索引。

如果您认为您将根据包含集合的特定成员的父项来查询父项,请使用映射而不是数组。

有很多帖子说数组在 Cloud Firestore 上不能很好地工作,因为当您拥有可以被多个客户端更改的数据时,很容易混淆,因为您不知道发生了什么以及发生在哪个字段上。如果我使用地图并且用户想要编辑几个不同的字段,即使是完全相同的字段,我们通常都知道发生了什么。在数组中,情况有所不同。试着想想如果用户想要编辑索引 0 处的值,其他用户想要删除索引 0 处的值,你最终会得到非常不同的结果,为什么不,数组越界异常。所以带有数组的 Firestore 操作有点不同。因此,您不能在特定索引处执行诸如插入、更新或删除之类的操作。但如果不 不关心将元素存储到数组中的确切顺序,那么您应该使用数组。Firestore 几天前添加了一些功能来添加或删除特定元素,但前提是不关心它们的确切位置。看这里官方文档。

总之,只有当您需要将数据一起显示时,才将数据放在同一个文档中。另外,不要让它们太大,这样您就需要下载比实际需要更多的数据。当您想要搜索数据的各个字段或希望数据有增长空间时,将数据放入集合中。如果您想根据该数据搜索父对象,请将您的数据保留为地图字段。如果您有通常用作标志的项目,请继续使用数组。

另外,不用担心Firestore 中的慢查询


推荐阅读