簡體   English   中英

Firestore:如何查詢文檔集合中的地圖對象?

[英]Firestore: How to query a map object inside a collection of documents?

我的目標:

網絡應用程序(類似於 Google Drive)有 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')

上面的查詢不起作用,因為它需要 Firestore 為roles.alice、roles.bob、roles.david、roles.jane 和roles.[all_uid] 建立索引。


編輯 #1:找到了一個相關的帖子(沒有答案)詢問Firestore 使用角色查詢

現在您可以過濾...

db
  .collection('orders')
  .where('orderDetails.status', '==', 'OPEN')

它將檢查屬性狀態的字段orderDetails是否等於“OPEN”

您無法使用實際的數據庫結構以不需要為每個用戶分別創建索引的方式實現這一點。 為了解決這個問題,你應該復制你的數據。 這種做法稱為denormalization ,是 Firebase 的常見做法。 如果您不熟悉 NoQSL 數據庫,我建議您觀看此視頻, Firebase 數據庫的非規范化是正常的,以便更好地理解。 它適用於 Firebase 實時數據庫,但同樣的規則適用於 Cloud Firestore。

此外,當您復制數據時,需要記住一件事。 與添加數據的方式相同,您需要維護它。 換句話說,如果你想更新/刪除一個項目,你需要在它存在的每個地方都做。

話雖如此,您應該創建另一個名為userStories集合,您應該在其中添加用戶為owner所有故事作為文檔。 所以你的數據庫結構應該類似於:

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

所以像這樣的查詢:

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

將工作得很好。

在此處輸入圖片說明 如果我弄錯了,請告訴我,但您的查詢似乎確實有效。 作為實驗,我添加了您在問題中給出的結構,並在 firebase 控制台中成功執行了查詢。

這不是你想要的嗎? 我還確保“in”運算符也適用於這種情況。 通過這種方式,您可以詢問用戶是所有者和評論者的哪些故事。

在此處輸入圖片說明

這會產生正確的結果: 在此處輸入圖片說明

這是不可能的,因此我們需要在 NoSQL 中復制數據。

一種可能的數據結構是

/故事/{故事ID}

{
  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)

雖然我們可以查詢“與我共享”的網絡應用程序 UI

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

答案的靈感來自@Doug Stevenson 評論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM