C# MongoDB Driver with GridFS

本文关键字:GridFS with Driver MongoDB | 更新日期: 2023-09-27 17:48:57

谁能告诉我存储与单个mongo文档相关的多个图像的最佳方法?

我的用例是在"profile"集合中有一个"user"文档。这个文档有关于用户的元数据(电子邮件地址,电话#..)。
然后我们可以上传一个用户的多张图片。

我们使用GridFS将图像存储在文件集合中,并且我从GridFS获得上传图像的id。

将图像对象与上传它的用户对象关联起来的最佳方法是什么?我可以将用户的ObjectID放在图像对象....的元数据中或者我可以把ObjectID放在用户文档中(并创建一个图像集合)。

我们正在使用c#驱动程序,所以如果有人有任何我用例的例子,那就太好了。

谢谢MJD

C# MongoDB Driver with GridFS

我将在用户文档中存储DBRef的数组,以创建更强的关联。除了图像的唯一ID之外,这为关联(即目标集合)提供了更多上下文。

至于在图像中存储ID,出于以下几个原因,我将跳过它:

  • 您不希望必须经常维护双引用。虽然由于文档数据库的脱节性质,这有时是必要的,但这种关联很容易从反向查找中推断出来。
  • 索引用户对象中的引用数组将通过简单的反向查找从图像中获得用户信息。这是一个微不足道的查询,它的开销可以忽略不计(如果有的话)。

如果需求发生变化,允许一个图像代表多个用户,那么只有单向松散关联可以帮助您的实现面向未来。

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

    }

}

我同意@Jake的观点,没有必要在image中存储userId。

我喜欢在用户文档中不仅存储图像集合ObjectId,而且还存储一些更多的信息(如文件名,mb一些元数据)。

使用这种方法,如果您想要显示有关用户下载的信息(文件名,文件链接),则不需要按id加载文件。

所以我建议这样的模式:

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