地图和数组字段的索引限制(汇总在集合中?)

时间:2018-10-01 06:05:46

标签: google-cloud-firestore

我正在构建一个应用程序,用户可以在其中发布猫的图片,而其他用户可能会“喜欢”这些图片。

我需要能够查询最喜欢的图片,以及查询特定用户喜欢的图片。

我正在尝试决定如何为“喜欢”数据建模。特别是,有以下选项:

  1. 将喜欢的照片存储在猫照片文档中作为地图。喜欢:

    //cats:
    {
        likes: {
            [userId: string]: {
                user: {
                    id: string,
                    displayName: string,
                    profilePhoto: string
                },
                createTime: Date
            }
        },
        nLikes: number
    }
    
  2. 将喜欢的照片以数组的形式存储在猫照片文档中,将用户数据存储为未索引的地图,例如:

    //cats
    {
        ...
        likeIds: string[], // userIds
        likeUsers: {  // <- unindexed
            [userId: string]: ...
        }  
    }
    
  3. 创建一个具有/likes引用的新顶级集合catId

我认为,因为我最经常想获得一张特定图片的所有赞(并显示喜欢图片的人的用户名和个人资料照片),因此使用地图(选项1)很有意义。因为我可以说类似这样的话,这也使我的查询更简单:

db.collection('cats').where(`likes.${userId}.user.id`, '==', userId)

获取给定用户喜欢的所有cat文档。

另一方面,在阅读了这些limitations on indexes之后,我担心上面的userId映射将如何与索引交互。由于在我的收藏夹中的所有文档中,都会出现许多不同的userId条目(实际上,如果我的猫图片共享站点成功,那么条目数百万个)。因为我假设为集合中任何文档中的每个唯一键值都创建了一个索引,所以它看起来很快就会超出索引限制。

选项2允许使用array-contains查询来查找某些用户喜欢的猫。但是,我不知道数组和映射与索引交互的方式是否不同。在Firestore内部,将数组转换为{[userId: string]: true}映射的可能性似乎很高,在索引编制方面,与选项1相同。

最后,使用选项3(顶级/likes集合)绝对可以保证索引大小,并允许我以清晰的方式查询内容。但是,这似乎违背了Firestore的理念,即对数据进行非规范化以优化读取。对于我最受欢迎的猫咪图片(每天可能有成千上万的用户喜欢并且每天有成千上万的人观看),我现在需要进行多次读取才能检索喜欢该照片的人的用户信息,并进行成本核算$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$预防故障全部故障停机掉就使应用停机了。

因此,总而言之,我对选项1和2中不良索引交互的担忧是否合法?如果userId(在集合中的所有文档中)的数量变大,它们是否将那些作为可行的策略消除?即使读取次数/使用该应用程序的成本增加了,在这种情况下我还是会被迫进入选项3?

谢谢!

0 个答案:

没有答案