开发者

C# MongoDB Driver with GridFS

Can anyone tell me the best way to store multiple images related to a single mongo document?

My use-case is that I have a “user” doc in the “profile” collection. This document has metadata about the user(email address, phone #..).

Then we have the ability to upload multiple images about a user.

We are using GridFS to store the images in the files collection, and I get back the id of the uploaded image from GridFS.

What is the best way to relate that image object back to the user object that uploaded it? I can put the User’s ObjectID in the metadata of the Image Object….or I can put the ObjectID in the User Doc(and create a 开发者_开发百科collection of Images).

We are using the C# driver…so if anyone has any examples of my use-case…that would be great.

Thanks MJD


I would store an array of DBRefs in the user's document to create a stronger association. This affords more context to the association (i.e., the target collection) in addition to just the unique ID of the image.

As for storing the ID in the image, I would skip it for a few reasons:

  • You don't want to have to constantly maintain the dual references. While this is sometimes a necessity due to the disjointed nature of document databases, the association is easy to infer from the reverse lookup.
  • Indexing the array of references in the user object will get you the user info from an image with a simple reverse-lookup. This is a trivial query and will result in negligible overhead (if any).

Having only the one-way loose association helps to future-proof your implementation should the requirements ever change to allow a single image to represent multiple users.


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; }


    }


}


I am agree with @Jake, that no need to store userId in image.

I like to store not only collection of images ObjectId in the user document, but also some more information (like file name, mb some metadata).

With such approch you no need load files by ids if you want display information about user downloads (file name, link to the file).

So i suggest schema like this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜