第五节 MongoDB GridFS文件存储

本节探讨问题:

  • 回顾对象存取
  • 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();
}
}
}

标签属性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的脚本存储

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

默认脚本是存到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"); //复制新的文件
}
}
}

看一下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>

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());

Mongo的入门就到这里了,后面将继续探讨Mongo的备份,自动分片等功能。

posted on 2011-06-16 00:52  小城岁月  阅读(6818)  评论(0编辑  收藏  举报

导航

面朝大海,春暖花开!