本节探讨问题:
- 回顾对象存取
- GFS文件存储
- samus Mongo配置
一、回顾对象存取
上一节我们探讨了MongoDB对象的存储,这一节我们再补充一些。
View Code
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文件夹下的单元测试类。
View Code
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的脚本存储
View Code
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建立关联。
看源码很简单直,直接整理一下
View Code
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的配置文件结构
View Code
<
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中
以下代码部分
View Code
//
动态注入连接及映射关关
// 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的备份,自动分片等功能。