目前,我的Firestore查询技术存在一些问题。根据我最近发布的这个stackoverflow帖子,Querying with two array with firestore security rules
答案是建议将“id”添加到对象中,并以键作为id,而值仅是“true”。我已经完成了这一步,现在我的结构如下所示:
这让我有了这个查询:
db.collection('Depots')
.where(`products.${productId}`, '==', true)
.where(`users.${userId}`, '==', true)
.where('created', '>', 1585998560500)
.orderBy('created', 'asc')
.get();
该查询使我抛出错误,要求创建索引:但是,这会尝试索引特定的对象键,即
QXooVYGBIFWKo6C
这样products.QXooVYGBIFWKo6C
。从本质上讲,这不是我想要的,因为此查询会发生变化,并且可能具有无限的可能性,这意味着我必须为每个键条目创建另一个索引才能查询它。有什么办法解决这个问题?由于查询中使用的运算符不同,我假设它需要为该查询建立索引,因此我想知道是否存在针对此问题的解决方法。
提前非常感谢您。
最佳答案
在聊天中讨论之后,这是我建议的起点。谁知道最终架构会是什么样子,但我认为这一点或与之非常接近。您说一个用户可以同时存在于多个软件仓库中,并且多个软件仓库可以同时包含相同的产品。您还说过,一个仓库在给定时间永远不能拥有40个以上的用户,因此40个用户的阵列肯定不会侵犯Firestore的1,048,576
字节的文档限制。
[collection]
<documentId>
- field: value
[depots]
<UUID>
- depotId: string "depot456"
- productCount: num 5,000
<UUID>
- depotId: string "depot789"
- productCount: num 4,500
[products]
<UUID>
- productId: string "lotion123"
- depotId: string "depot456"
- users: [string] ["user10", "user27", "user33"]
<UUID>
- productId: string "lotion123"
- depotId: string "depot789"
- users: [string] ["user10", "user17", "user50"]
[users]
<userId>
- depots: [string] ["depot456", "depot999"]
<userId>
- depots: [string] ["depot333", "depot999"]
在NoSQL中,存储很便宜,并且计算并不会使您的数据非正常化,从而不会使查询变得可能和高效(快速又便宜)。
要在单个查询中查找
user10
和lotion123
都为true的所有软件仓库,请查询productId
等于x
和users
数组包含y
的产品集合,并从这些结果中收集depotId
值。如果要保留数组包含的其他操作,则必须进一步对数据进行规范化(将数组替换为单个用户)。或者,您可以将此查询分为两个单独的查询。使用此模型,当用户离开仓库时,获取
users
数组包含该用户的所有产品,然后从数组中删除该userId
。当用户加入软件仓库时,获取depotId
等于x
的所有产品,并将该userId
附加到数组中。观看此视频以及Rick的其他视频,以牢固地掌握NoSQL:https://www.youtube.com/watch?v=HaEPXoXVf2k