web-dev-qa-db-ja.com

Firestore:ドキュメントのコレクション内のマップオブジェクトをクエリする方法は?

私の目的:

Webアプリ(Googleドライブに類似)には2つの画面があります。

最初の画面は「マイストーリー」で、私が所有者であるすべてのストーリードキュメントが表示されます。

2番目の画面は「私と共有」です。ここには、私が読者、ライター、またはコメンターであるすべてのストーリードキュメントが表示されます。

これがあります/ stories/{storyid}

{
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter"
    // ...
  }
}

完全なデータ構造のリファレンス: https://firebase.google.com/docs/firestore/solutions/role-based-access

質問:上記の目的を満たすために、以下のクエリをどのように記述しますか?

db
.collection('stories')
.where(`roles.${uid}`, '==', 'owner')

上記のクエリは、roles.alice、roles.bob、roles.david、roles.jane、roles。[all_uid]。


編集#1:関連する投稿が見つかりました(回答なし) Firestore querying with roles

4

ユーザーごとに個別にインデックスを作成する必要がない方法で、実際のデータベース構造でこれを実現することはできません。これを解決するには、データを複製する必要があります。このプラクティスはdenormalizationと呼ばれ、Firebaseに関しては一般的なプラクティスです。 NoQSLデータベースを初めて使用する場合は、このビデオをご覧になることをお勧めします 非正規化はFirebaseデータベースでは正常です 理解を深めるため。これはFirebaseリアルタイムデータベース用ですが、Cloud Firestoreにも同じルールが適用されます。

また、データを複製する場合は、留意すべきことが1つあります。データを追加するのと同じ方法で、データを維持する必要があります。つまり、アイテムを更新/削除する場合は、存在するすべての場所で行う必要があります。

つまり、userStoriesという名前の別のコレクションを作成する必要があります。この場合、ユーザーがownerであるすべてのストーリーをドキュメントとして追加する必要があります。したがって、データベース構造は次のようになります。

Firestore-root
   |
   --- userStories (collection)
         |
         --- uid (document)
              |
              --- allStories (collection)
                     |
                     --- storyId
                           |
                           --- role: "owner"

したがって、次のようなクエリ:

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

完全に正常に動作します。

6
Alex Mamo

したがって、NoSQLでデータを複製する必要はありません。

考えられるデータ構造の1つは

/ stories/{storyid}

{
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter",
    mary: "writer",
    // ...
  },
  owner: "alice", // newly added
  shared: ["bob", "david", "jane", "mary"] // newly added
  // alice, bob, david, jane, mary are firebase auth uid
}

これで、WebアプリのUI「My Story」をクエリできます

db
.collection('stories')
.where('owner', '==', uid)

「Shared with me」のWebアプリUIをクエリできますが

db
.collection('stories')
.where('shared', 'array_contains', uid)

回答は、@ Doug Stevensonのコメントに触発されています。

0

enter image description here 間違っている場合はお知らせください。クエリは実際に機能するようです。実験として、質問で指定した構造を追加し、Firebaseコンソールでクエリを正常に実行しました。

これはあなたが目指していることではありませんか?また、 "in"演算子がこのケースでも機能することを確認しました。このようにして、ユーザーが所有者お​​よびコメント者であるストーリーを尋ねることができます。

enter image description here

これは正しい結果を引き出します: enter image description here

0
Grahambo