第五节 MongoDB GridFS文件存储
本节探讨问题:
- 回顾对象存取
- GFS文件存储
- samus Mongo配置
一、回顾对象存取
上一节我们探讨了MongoDB对象的存储,这一节我们再补充一些。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using MongoDB;
using MongoDB.Linq;
using MongoDB.Attributes;
namespace Demo
{
class Program
{
public class Person
{
[MongoAlias("fn")] //标记此属性存入MongoDB中的字段名
public string FirstName { get; set; }
[MongoAlias("ln")]
public string LastName { get; set; }
[MongoAlias("age")]
public int Age { get; set; }
[MongoAlias("add")]
public Address PrimaryAddress { get; set; }
[MongoAlias("otherAdds")]
public List<Address> Addresses { get; set; }
[MongoAlias("emps")]
public int[] EmployerIds { get; set; }
public string MidName { get; set; }
public Oid LinkedId { get; set; }
}
public class Address
{
[MongoAlias("city")]
public string City { get; set; }
public bool IsInternational { get; set; }
public AddressType AddressType { get; set; }
}
public enum AddressType
{
Company,
Private
}
public class PersonWrapper
{
public Person Person { get; set; }
public string Name { get; set; }
public PersonWrapper(Person person, string name)
{
Person = person;
Name = name;
}
}
static void Main(string[] args)
{
Mongo mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
IMongoDatabase simple = mongo["simple"];
var Collection = simple.GetCollection<Person>("people");
//var DocumentCollection = simple.GetCollection("people");
Collection.Insert(
new Person
{
FirstName = "Bob",
LastName = "McBob",
Age = 42,
PrimaryAddress = new Address { City = "London" },
Addresses = new List<Address>
{
new Address { City = "London" },
new Address { City = "Tokyo" },
new Address { City = "Seattle" }
},
EmployerIds = new[] { 1, 2 }
}, true);
Collection.Insert(
new Person
{
FirstName = "Jane",
LastName = "McJane",
Age = 35,
PrimaryAddress = new Address { City = "Paris" },
Addresses = new List<Address>
{
new Address { City = "Paris" }
},
EmployerIds = new[] { 1 }
}, true);
Collection.Insert(
new Person
{
FirstName = "Joe",
LastName = "McJoe",
Age = 21,
PrimaryAddress = new Address { City = "Chicago" },
Addresses = new List<Address>
{
new Address { City = "Chicago" },
new Address { City = "London" }
},
EmployerIds = new[] { 3 }
}, true);
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using MongoDB;
using MongoDB.Linq;
using MongoDB.Attributes;
namespace Demo
{
class Program
{
public class Person
{
[MongoAlias("fn")] //标记此属性存入MongoDB中的字段名
public string FirstName { get; set; }
[MongoAlias("ln")]
public string LastName { get; set; }
[MongoAlias("age")]
public int Age { get; set; }
[MongoAlias("add")]
public Address PrimaryAddress { get; set; }
[MongoAlias("otherAdds")]
public List<Address> Addresses { get; set; }
[MongoAlias("emps")]
public int[] EmployerIds { get; set; }
public string MidName { get; set; }
public Oid LinkedId { get; set; }
}
public class Address
{
[MongoAlias("city")]
public string City { get; set; }
public bool IsInternational { get; set; }
public AddressType AddressType { get; set; }
}
public enum AddressType
{
Company,
Private
}
public class PersonWrapper
{
public Person Person { get; set; }
public string Name { get; set; }
public PersonWrapper(Person person, string name)
{
Person = person;
Name = name;
}
}
static void Main(string[] args)
{
Mongo mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
IMongoDatabase simple = mongo["simple"];
var Collection = simple.GetCollection<Person>("people");
//var DocumentCollection = simple.GetCollection("people");
Collection.Insert(
new Person
{
FirstName = "Bob",
LastName = "McBob",
Age = 42,
PrimaryAddress = new Address { City = "London" },
Addresses = new List<Address>
{
new Address { City = "London" },
new Address { City = "Tokyo" },
new Address { City = "Seattle" }
},
EmployerIds = new[] { 1, 2 }
}, true);
Collection.Insert(
new Person
{
FirstName = "Jane",
LastName = "McJane",
Age = 35,
PrimaryAddress = new Address { City = "Paris" },
Addresses = new List<Address>
{
new Address { City = "Paris" }
},
EmployerIds = new[] { 1 }
}, true);
Collection.Insert(
new Person
{
FirstName = "Joe",
LastName = "McJoe",
Age = 21,
PrimaryAddress = new Address { City = "Chicago" },
Addresses = new List<Address>
{
new Address { City = "Chicago" },
new Address { City = "London" }
},
EmployerIds = new[] { 3 }
}, true);
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
}
}
标签属性MongoAlias标记的字段名,在存入MongoDB的时候会自动切换为对应的名称,当对象与数据库字段不匹配时可通过此标签属性解决。
读取数据一些常用LINQ写法,具体更多的方法可参照源码的MongoDB.Tests中LINQ文件夹下的单元测试类。

static void Main(string[] args)
{
Mongo mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
IMongoDatabase simple = mongo["simple"];
IMongoCollection<Person> Collection = simple.GetCollection<Person>("people");
//以上为一些常用的LINQ定法
var anyone = Collection.Linq().Any(x => x.Age <= 21);
var people = Collection.Linq().Where(x => !x.PrimaryAddress.IsInternational);
var people1 = Collection.Linq()
.Select(x => new { Name = x.FirstName + x.LastName, x.Age })
.Where(x => x.Age > 21)
.Select(x => x.Name);
var people2 = Collection.Linq().ToList();
var people3 = Collection.Linq().Where(x => x.FirstName.Contains("C"));
//按指定条数分页
var people4 = Collection.Linq().OrderBy(x => x.Age).Skip(2).Take(1).ToList();
var people5 = (from p in Collection.Linq()
where p.FirstName.StartsWith("J")
select p).ToList();
//分组
var group = from u in people2.AsEnumerable()
group u by u.FirstName
into g
select g;
var list = Collection.Find(x => x.Age > 21).Documents;
var exp = Collection.FindAll().Limit(5).Skip(5).Sort("x");
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
{
Mongo mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
IMongoDatabase simple = mongo["simple"];
IMongoCollection<Person> Collection = simple.GetCollection<Person>("people");
//以上为一些常用的LINQ定法
var anyone = Collection.Linq().Any(x => x.Age <= 21);
var people = Collection.Linq().Where(x => !x.PrimaryAddress.IsInternational);
var people1 = Collection.Linq()
.Select(x => new { Name = x.FirstName + x.LastName, x.Age })
.Where(x => x.Age > 21)
.Select(x => x.Name);
var people2 = Collection.Linq().ToList();
var people3 = Collection.Linq().Where(x => x.FirstName.Contains("C"));
//按指定条数分页
var people4 = Collection.Linq().OrderBy(x => x.Age).Skip(2).Take(1).ToList();
var people5 = (from p in Collection.Linq()
where p.FirstName.StartsWith("J")
select p).ToList();
//分组
var group = from u in people2.AsEnumerable()
group u by u.FirstName
into g
select g;
var list = Collection.Find(x => x.Age > 21).Documents;
var exp = Collection.FindAll().Limit(5).Skip(5).Sort("x");
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
再来看一下Mongo的脚本存储

static void Main(string[] args)
{
Mongo mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
IMongoDatabase simple = mongo["simple"];
DatabaseJavascript javascript = simple.Javascript;
string name = "DoAdd";
var func = "function(x, y){return x + y;}";
javascript.Add(name, func);
string name1 = "DoEdit";
var func1 = new Code("function(x,y){return x + y;}");
javascript.Add(name1, func1);
string functionName = javascript.GetFunctionNames()[0];
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
{
Mongo mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
IMongoDatabase simple = mongo["simple"];
DatabaseJavascript javascript = simple.Javascript;
string name = "DoAdd";
var func = "function(x, y){return x + y;}";
javascript.Add(name, func);
string name1 = "DoEdit";
var func1 = new Code("function(x,y){return x + y;}");
javascript.Add(name1, func1);
string functionName = javascript.GetFunctionNames()[0];
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
默认脚本是存到system.js这个集合中的,samus还提供部分文档对象类,都很简单,参照源码很容易看懂。
二、GFS文件存储
Mongo GFS的文件表是由 表名.files和 表名.chunks 构成,前者是文件信息构成,后者是文件的内容,两者通过_id与files_id建立关联。
看源码很简单直,直接整理一下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using MongoDB;
using MongoDB.GridFS;
using System.IO;
namespace Demo
{
class Program
{
static Mongo mongo;
static IMongoDatabase simple;
static void Main(string[] args)
{
mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
simple = mongo["simple"];
//GridFile创建默认文件表fs
//Test1(simple);
//GridFile新建文件表
//Test2("createnew.txt");
//GridFileInfo 读取MongoDB中文件指定文件信息
//Test3("createnew.txt");
//读取指定物理文件存入MongoDB中
//Test4();
//删除文件
//Test5();
////另外的查找方式
//GridFile fs = new GridFile(simple, "gfcreate");
//var doc = fs.Files.FindOne(new Document("filename", "cctv.txt"));
//var chunks = fs.Chunks.FindOne(new Document("files_id",doc.Id));
////fs.Move("A.txt", "B.txt"); //移动文件
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
private static void Test5()
{
GridFile fs = new GridFile(simple, "gfcreate");
fs.Delete(new Document("filename", "cctv.txt"));
}
private static void Test4()
{
string filename = "E:\\cctv.txt";
GridFile gf = new GridFile(simple, "gfcreate");
using (GridFileStream gfs = gf.Create("cctv.txt", FileMode.Create))
{
byte[] bytes = File.ReadAllBytes(filename);
gfs.Write(bytes, 0, bytes.Length);
}
Test3("cctv.txt");
}
private static void Test3(string filename)
{
GridFileInfo gfInfo = new GridFileInfo(simple, "gfcreate", filename); //类似File与FileInfo
using (GridFileStream gfs = gfInfo.OpenRead())
{
TextReader reader = new StreamReader(gfs);
Console.WriteLine(reader.ReadToEnd());
reader.Close();
}
}
private static string Test2(string filename)
{
//新建表 gfcreate.files/gfcreate.chunks
GridFile gf = new GridFile(simple, "gfcreate");
using (GridFileStream gfs = gf.Create(filename, FileMode.CreateNew))
{
object id = gfs.GridFileInfo.Id; //获取文件的ID即Mongo中_id
TextWriter tw = new StreamWriter(gfs);
tw.WriteLine("test");
tw.Close();
Console.WriteLine(id.ToString());
//simple["gfcreate.chunks"].Count(new Document().Add("files_id", id)); //查找chunks对应id文件数
}
return filename;
}
private static void Test1()
{
//取默认表(默认为创建名fs的表,但是在MongoDB为分成fs.files和fs.chunks两张表
//前者存储文件信息,后者存储文件内容.两张表通过_id与files_id建立关联
GridFile fs = new GridFile(simple); //默认读取的集合表名是fs
fs.Exists("cctv.txt"); // 判断fs表中是否有这个文件
GridFileStream gfs = fs.Create("original.txt"); //创建一个新文件
gfs.WriteByte(1);
gfs.Seek(1024 * 256 * 2, SeekOrigin.Begin);
gfs.WriteByte(2);
gfs.Close();
fs.Copy("original.txt", "copy.txt"); //复制新的文件
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using MongoDB;
using MongoDB.GridFS;
using System.IO;
namespace Demo
{
class Program
{
static Mongo mongo;
static IMongoDatabase simple;
static void Main(string[] args)
{
mongo = new Mongo("Server=127.0.0.1:27017");
mongo.Connect();
simple = mongo["simple"];
//GridFile创建默认文件表fs
//Test1(simple);
//GridFile新建文件表
//Test2("createnew.txt");
//GridFileInfo 读取MongoDB中文件指定文件信息
//Test3("createnew.txt");
//读取指定物理文件存入MongoDB中
//Test4();
//删除文件
//Test5();
////另外的查找方式
//GridFile fs = new GridFile(simple, "gfcreate");
//var doc = fs.Files.FindOne(new Document("filename", "cctv.txt"));
//var chunks = fs.Chunks.FindOne(new Document("files_id",doc.Id));
////fs.Move("A.txt", "B.txt"); //移动文件
mongo.Disconnect();
mongo.Dispose();
Console.ReadLine();
}
private static void Test5()
{
GridFile fs = new GridFile(simple, "gfcreate");
fs.Delete(new Document("filename", "cctv.txt"));
}
private static void Test4()
{
string filename = "E:\\cctv.txt";
GridFile gf = new GridFile(simple, "gfcreate");
using (GridFileStream gfs = gf.Create("cctv.txt", FileMode.Create))
{
byte[] bytes = File.ReadAllBytes(filename);
gfs.Write(bytes, 0, bytes.Length);
}
Test3("cctv.txt");
}
private static void Test3(string filename)
{
GridFileInfo gfInfo = new GridFileInfo(simple, "gfcreate", filename); //类似File与FileInfo
using (GridFileStream gfs = gfInfo.OpenRead())
{
TextReader reader = new StreamReader(gfs);
Console.WriteLine(reader.ReadToEnd());
reader.Close();
}
}
private static string Test2(string filename)
{
//新建表 gfcreate.files/gfcreate.chunks
GridFile gf = new GridFile(simple, "gfcreate");
using (GridFileStream gfs = gf.Create(filename, FileMode.CreateNew))
{
object id = gfs.GridFileInfo.Id; //获取文件的ID即Mongo中_id
TextWriter tw = new StreamWriter(gfs);
tw.WriteLine("test");
tw.Close();
Console.WriteLine(id.ToString());
//simple["gfcreate.chunks"].Count(new Document().Add("files_id", id)); //查找chunks对应id文件数
}
return filename;
}
private static void Test1()
{
//取默认表(默认为创建名fs的表,但是在MongoDB为分成fs.files和fs.chunks两张表
//前者存储文件信息,后者存储文件内容.两张表通过_id与files_id建立关联
GridFile fs = new GridFile(simple); //默认读取的集合表名是fs
fs.Exists("cctv.txt"); // 判断fs表中是否有这个文件
GridFileStream gfs = fs.Create("original.txt"); //创建一个新文件
gfs.WriteByte(1);
gfs.Seek(1024 * 256 * 2, SeekOrigin.Begin);
gfs.WriteByte(2);
gfs.Close();
fs.Copy("original.txt", "copy.txt"); //复制新的文件
}
}
}
看一下Mongo.exe中结果:
samus源码很简洁也很简单,很容易学习理解。
三、samus Mongo配置
我来看一下Mongo的配置文件结构

<configuration>
<configSections>
<section name="mongo" type="MongoDB.Configuration.MongoConfigurationSection, MongoDB" />
<section name="mongoNonDefaultName" type="MongoDB.Configuration.MongoConfigurationSection, MongoDB" />
</configSections>
<mongo>
<connections>
<add key="local21018" connectionString="Server=127.0.0.1:27018" />
<add key="auth" connectionString="Server=127.0.0.1:27019" />
<add key="default" />
<add key="tests" connectionString="Server=127.0.0.1:27017" />
</connections>
</mongo>
<mongoNonDefaultName>
<connections>
<add key="local21018" connectionString="Server=127.0.0.1:27017" />
</connections>
</mongoNonDefaultName>
<appSettings>
<add key="tests" value="Server=127.0.0.1:27017" />
<add key="auth" value="Server=127.0.0.1:27018" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
</configuration>
<configSections>
<section name="mongo" type="MongoDB.Configuration.MongoConfigurationSection, MongoDB" />
<section name="mongoNonDefaultName" type="MongoDB.Configuration.MongoConfigurationSection, MongoDB" />
</configSections>
<mongo>
<connections>
<add key="local21018" connectionString="Server=127.0.0.1:27018" />
<add key="auth" connectionString="Server=127.0.0.1:27019" />
<add key="default" />
<add key="tests" connectionString="Server=127.0.0.1:27017" />
</connections>
</mongo>
<mongoNonDefaultName>
<connections>
<add key="local21018" connectionString="Server=127.0.0.1:27017" />
</connections>
</mongoNonDefaultName>
<appSettings>
<add key="tests" value="Server=127.0.0.1:27017" />
<add key="auth" value="Server=127.0.0.1:27018" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
</configuration>
MongoConfigurationSection包含一个静态属性Default,这个属性会读取配置文件中对应Section节点的Mongo服务器列表。
也可以动态注入到MongoConfigurationBuilder中
以下代码部分

//动态注入连接及映射关关
//var config = new MongoConfigurationBuilder();
//config.ConnectionString("Server=127.0.0.1");
//mongo = new Mongo(config.BuildConfiguration()
//读配置中多服务器列表
mongo = new Mongo(MongoConfiguration.Default);
mongo.Connect();
simple = mongo["simple"];
var docCollection = simple.GetCollection("Employee");
var doc = docCollection.FindOne(new Document("Name", "http"));
Console.WriteLine(doc["Age"].ToString());
//var config = new MongoConfigurationBuilder();
//config.ConnectionString("Server=127.0.0.1");
//mongo = new Mongo(config.BuildConfiguration()
//读配置中多服务器列表
mongo = new Mongo(MongoConfiguration.Default);
mongo.Connect();
simple = mongo["simple"];
var docCollection = simple.GetCollection("Employee");
var doc = docCollection.FindOne(new Document("Name", "http"));
Console.WriteLine(doc["Age"].ToString());
Mongo的入门就到这里了,后面将继续探讨Mongo的备份,自动分片等功能。
分类:
MongoDB
标签:
mongodb
, mongo for .net
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述