Firestore:如何查询文档集合内的地图对象?

cho*_*Bao 1 firebase angularfire2 google-cloud-firestore angularfire5

我的目标:

网络应用程序(类似于Google云端硬盘)有2个屏幕。

第一个屏幕是“我的故事”,其中显示了我是所有者的所有故事文档。

第二个屏幕是“与我共享”,其中显示了我是读者,作家或评论者的所有故事文档。

我们有这个/ stories / {storyid}

{
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter"
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

完整的数据结构参考:https : //firebase.google.com/docs/firestore/solutions/role-based-access

问题:如何编写以下查询以实现上述目标?

db
.collection('stories')
.where(`roles.${uid}`, '==', 'owner')
Run Code Online (Sandbox Code Playgroud)

上面的查询不起作用,因为它将要求Firestore索引role.alice,roles.bob,roles.david,roles.jane和role。[all_uid]。


编辑#1:找到相关帖子(无答案),询问有关带角色的Firestore查询

Cri*_*ris 9

现在您可以过滤...

db
  .collection('orders')
  .where('orderDetails.status', '==', 'OPEN')
Run Code Online (Sandbox Code Playgroud)

它将检查属性状态的字段orderDetails是否等于“OPEN”

  • 您能否详细说明您的建议如何适用于这个问题? (2认同)

Ale*_*amo 5

您无法通过实际的数据库结构来实现此目的,而不必为每个用户分别创建索引。要解决这个问题,您应该复制数据。denormalization在Firebase中,这种做法被称为并且是一种常见的做法。如果您是NoQSL数据库的新手,建议您观看此视频,对于更好的了解,Firebase数据库的非规范化是正常的。它适用于Firebase实时数据库,但相同的规则适用于Cloud Firestore。

另外,在复制数据时,请记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。

话虽如此,您应该创建另一个名为的集合userStories,在其中应将用户所在的所有故事添加为文档owner。因此,您的数据库结构应类似于以下内容:

Firestore-root
   |
   --- userStories (collection)
         |
         --- uid (document)
              |
              --- allStories (collection)
                     |
                     --- storyId
                           |
                           --- role: "owner"
Run Code Online (Sandbox Code Playgroud)

所以这样的查询:

db.collection('userStories').doc(${uid})
    .collection('allStories').where(`role`, '==', 'owner');
Run Code Online (Sandbox Code Playgroud)

会完美地工作。

  • @ choopage-JekBao不,我也曾经被帮助过,我想以同样的方式帮助别人;) (6认同)