地图字段上的Firestore范围查询

时间:2019-02-06 20:46:09

标签: firebase google-cloud-firestore

我有一个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展平将是一个解决方案,但并非最优雅。有什么建议吗?

1 个答案:

答案 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的新集合或子集合来扩展数据结构,以允许反向查找,这些集合或子集合可以将用户的所有对话作为文档保存。对于简单的查询,不需要索引。