首页 > 解决方案 > 当自定义索引不是 Firestore 中的选项时该怎么办

问题描述

在我的 Cloud Firestore 数据库中,我有一个集合users和一个events. Auser可以通过向所有者请求它们来参加多个事件,因此在每个事件中event我都会跟踪这一点,如下所示:

在此处输入图像描述 获取 auser参与的所有事件的查询是:

String participating = "participants_id." + myUserID;
query = FirebaseFirestore.getInstance().collection("events").whereEqualTo(participating, true);

问题是,如果我想对这些结果进行分页,我需要orderlimit查询,这需要一个自定义索引。因此,每个字段都需要此索引"participants_id." + myUserID,这是不可扩展的(最大自定义索引为 200)。

那么我该如何解决呢?我可以对集合进行非规范化,并为每个在那里复制事件文档的用户events添加一个子集合。participating但如果可能的话,我宁愿避免非规范化,因为它变得有点混乱。有没有更好的选择?

标签: javaandroidfirebasegoogle-cloud-firestore

解决方案


Cloud Firestore自动在文档的各个字段上创建索引。跨多个字段的复杂索引只能在Firebase 控制台中手动创建。不幸的是,您不能以编程方式创建索引,至少目前是这样。

在您的场景中,您绝对应该使用非规范化。使用非规范化的一个原因是,文档的最大大小也有一个限制,即1Mib. 所以如果你有太多的参与者,你可以很快达到这个限制。请参阅此处Firestore 配额和限制

因此,您通常应该考虑扩充您的数据结构以允许反向查找。例如,我会添加一个participating子集合,您可以在其中保留每个用户的列表,或者您可以将其添加为顶级集合,您的数据库结构应如下所示:

Firestore-root
   |
   --- users (collection)
   |      |
   |      --- userId (document)
   |           |
   |           --- //user details
   |
   --- userEvents (collection)
   |     |
   |     --- userId (document)
   |           |
   |           --- events (collection)
   |                 |
   |                 --- eventId
   |                       |
   |                       --- //event details
   |
   --- events (collection)
         |
         --- eventId (document)
               |
               --- //event details

使用这种数据库结构,您可以非常快速地查询您的数据库以获取与特定用户对应的所有事件。据我所知,这些是您唯一的选择。


推荐阅读