2011-04-07 108 views
1

任何人都可以告訴我存儲與單個mongo文檔相關的多個圖像的最佳方法嗎?有GridFS的C#MongoDB驅動程序

我的用例是我在「個人資料」集合中有一個「用戶」文檔。該文檔包含有關用戶的元數據(電子郵件地址,電話號碼..)。
然後我們有能力上傳關於用戶的多個圖像。

我們使用GridFS將圖像存儲在文件集合中,並從GridFS獲取上傳圖像的ID。

將圖像對象與上傳它的用戶對象關聯的最佳方式是什麼?我可以把用戶的ObjectID放在Image Object的元數據中......或者我可以把ObjectID放在User Doc中(並創建一個Images的集合)。

我們使用的是C#驅動程序...所以如果任何人有我的用例的任何例子...那將是偉大的。

感謝 MJD

回答

4

我會存儲用戶的文檔中的DBRef秒的陣列來創建一個關聯性更強。除了圖像的唯一ID之外,這爲關聯(即,目標集合)提供了更多的上下文。

至於存儲圖像中的ID,我會跳過它有幾個原因:

  • 你不希望要不斷保持雙引用。雖然由於文檔數據庫的脫節本質,這有時是必需的,但從反向查找中很容易推斷出該關聯。
  • 索引用戶對象中的引用數組將通過簡單的反向查找從圖像中獲取用戶信息。這是一個微不足道的查詢,會導致可忽略的開銷(如果有的話)。

只有單向鬆散關聯有助於未來驗證您的實現,如果需求發生變化以允許單個圖像代表多個用戶。

1

我同意@Jake,不需要在圖像中存儲userId。

我喜歡不僅在用戶文檔中存儲圖像ObjectId的集合,而且還存儲一些更多信息(如文件名,mb某些元數據)。

如果您希望顯示有關用戶下載(文件名,鏈接到文件)的信息,則無需通過ID加載文件。

所以我建議的模式是這樣的:

User { _id, 
     .., 
     Images { 
       ImageId, 
       ImageName, 
       .. } 
    } 
+0

疑難雜症完全是有道理的......和我在做出這樣的轉變過程。還有一個問題。現在我有了DBRef,我用var ImageRef = profileDB.FetchDBRef(user.Images [0] .UserPhoto)取回了它。我如何獲得GridFS文檔的句柄。我會認爲ImageRef會給我流...但它沒有。謝謝MJD – 2011-04-07 15:55:50

2
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using MongoDB.Driver; 
using MongoDB.Driver.Linq; 
using MongoDB.Bson; 
using MongoDB.Driver.Builders; 
using MongoDB.Driver.GridFS; 
using System.IO; 
using System.Diagnostics; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      MongoServer ms = MongoServer.Create(); 
      string _dbName = "docs"; 

      MongoDatabase md = ms.GetDatabase(_dbName); 
      if (!md.CollectionExists(_dbName)) 
      { 
       md.CreateCollection(_dbName); 
      } 

      MongoCollection<Doc> _documents = md.GetCollection<Doc>(_dbName); 
      _documents.RemoveAll(); 
      //add file to GridFS 

      MongoGridFS gfs = new MongoGridFS(md); 
      MongoGridFSFileInfo gfsi = gfs.Upload(@"c:\mongodb.rtf"); 
      _documents.Insert(new Doc() 
      { 
       DocId = gfsi.Id.AsObjectId, 
       DocName = @"c:\foo.rtf" 
      } 
      ); 

      foreach (Doc item in _documents.FindAll()) 
      { 

       ObjectId _documentid = new ObjectId(item.DocId.ToString()); 
       MongoGridFSFileInfo _fileInfo = md.GridFS.FindOne(Query.EQ("_id", _documentid)); 
       gfs.Download(item.DocName, _fileInfo); 
       Console.WriteLine("Downloaded {0}", item.DocName); 
       Console.WriteLine("DocName {0} dowloaded", item.DocName); 

      } 



      Console.ReadKey(); 
     } 
    } 

    class Doc 
    { 
     public ObjectId Id { get; set; } 
     public string DocName { get; set; } 
     public ObjectId DocId { get; set; } 


    } 


}