我有一个conversations
的集合,每个对话都有一个hidden<Map>
,其中每个参与者都是键,并且具有布尔值,因此我可以查看他是否在对话结束时存档了对话。因此,查询如下所示:
store.conversations
.where( 'participants', 'array-contains', uid )
.where( `hidden.${uid}`, '==', false )
.orderBy( 'createdAt', 'desc' )
添加orderBy
时出现问题,这使其成为“范围”查询。因此,鉴于每个文档在hidden<Map>
中具有不同的键集,Firestore建议采取以下措施,这显然行不通:
participants Arrays
hidden.`48m6lKjwvKUOboAxlc0ppX2R7qF2` Ascending
createdAt Descending
我该如何解决?我猜想将Map
展平将是一个解决方案,但并非最优雅。有什么建议吗?
答案 0 :(得分:1)
Firestore建议采取以下措施,但显然不起作用:
participants Arrays
hidden.`48m6lKjwvKUOboAxlc0ppX2R7qF2` Ascending
createdAt Descending
您可以创建这样的索引,它会起作用,但是如果您的应用程序变得流行并且您将拥有大量的用户,则问题会上升。这意味着您必须为每个对话都创建一个索引,但这并不是一个好主意,因为涉及索引时,存在一些限制。根据有关Firestore usage and limits的官方文档:
数据库的最大组合索引数: 200
可以很快达到的数字。
我想展平地图是一种解决方案
您猜对了。这种做法也称为denormalization
,是Firebase的常见做法。如果您不熟悉NoQSL数据库,建议您观看此视频Denormalization is normal with the Firebase Database,以更好地理解。它用于Firebase实时数据库,但相同的规则适用于Cloud Firestore。
此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。
有关更多信息,请参见以下帖子中的答案:
因此,您可以对数据库进行非规范化并创建conversations
,而无需创建索引。对于您的用例,您应该考虑通过创建名为userConversations
的新集合或子集合来扩展数据结构,以允许反向查找,这些集合或子集合可以将用户的所有对话作为文档保存。对于简单的查询,不需要索引。