java - 使用 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
?
解决方案
随着集合中文档数量的增长和数组中项目数量的增长,这种搜索是否会变得非常低效?
问题不在于搜索将变得非常低效,问题在于文档有限制。因此,在您可以将多少数据放入文档时存在一些限制。根据有关使用和限制的官方文档:
文档的最大大小:1 MiB(1,048,576 字节)
如您所见,单个文档中的数据总量限制为 1 MiB。当我们谈论存储文本时,您可以存储几乎所有内容,但是随着您的数组变大,请注意此限制。
如果您在数组中存储大量数据并且这些数组应该由大量用户更新,那么您需要注意另一个限制。因此,每个文档每秒只能写入 1 次。因此,如果您遇到很多用户都试图一次将数据写入/更新到相同文档的情况,您可能会开始看到其中一些写入失败。所以,也要小心这个限制。
您可能已经注意到,Cloud Firestore 中的查询非常快,这是因为 Firestore 会自动为您文档中的任何字段创建索引。
如果您认为您将根据包含集合的特定成员的父项来查询父项,请使用映射而不是数组。
有很多帖子说数组在 Cloud Firestore 上不能很好地工作,因为当您拥有可以被多个客户端更改的数据时,很容易混淆,因为您不知道发生了什么以及发生在哪个字段上。如果我使用地图并且用户想要编辑几个不同的字段,即使是完全相同的字段,我们通常都知道发生了什么。在数组中,情况有所不同。试着想想如果用户想要编辑索引 0 处的值,其他用户想要删除索引 0 处的值,你最终会得到非常不同的结果,为什么不,数组越界异常。所以带有数组的 Firestore 操作有点不同。因此,您不能在特定索引处执行诸如插入、更新或删除之类的操作。但如果不 不关心将元素存储到数组中的确切顺序,那么您应该使用数组。Firestore 几天前添加了一些功能来添加或删除特定元素,但前提是不关心它们的确切位置。看这里官方文档。
总之,只有当您需要将数据一起显示时,才将数据放在同一个文档中。另外,不要让它们太大,这样您就需要下载比实际需要更多的数据。当您想要搜索数据的各个字段或希望数据有增长空间时,将数据放入集合中。如果您想根据该数据搜索父对象,请将您的数据保留为地图字段。如果您有通常用作标志的项目,请继续使用数组。
另外,不用担心Firestore 中的慢查询。
推荐阅读
- php - 无法在 PHP 8 交互式 shell 中输入 unicode 字符
- javascript - node.js - 在 http 获取请求 (API) 中使用 .csv 文件中的值
- javascript - 基于 ScreenResize 的 Vanilla Javascript 文档编写
- javascript - 在历史记录上处理具有 2 个条件的登录。仅在反应 js 中推送第二个条件
- php - Woocommerce 在购物车中显示含税价格,在结账时不显示
- javascript - 拖放 img 并覆盖
- elasticsearch - Elasticsearch 创建新文档太慢
- linux - 多台主机上的 Rsync 并行
- android - 如何解决 Google Pixel 手机在 Google Play 中的“无法安装”问题?
- php - PHP,Laravel 8 后端