[转]MongoDB学习 C#驱动操作MongoDB

下载驱动

驱动的下载有两种方式:一种是在C#项目中通过NuGet进行安装,另一种是通过下面的链接:https://github.com/mongodb/mongo-csharp-driver/releases 直接下载msi进行安装或zip压缩包。不管哪种方式,其主要的目的都是获取两个dll文件:MongoDB.Bson.dll、MongoDB.Driver.dll。这是在程序中需要引用的两个类库文件。

.NET版本要求

目前最新版的C#驱动是1.9.2,是在 .NET3.5的基础上构建的,所以使用C#驱动时,.NET的版本必须是3.5及其以上。

C#驱动主要包括两个命名空间:MongoDB.Bson和MongoDB.Driver。大多数的类是非线程安全的(线程安全的类有:MongoClient、MongoServer、MongoDatabase、MongoCollection、MongoGridFS、BsonSymbolTable)。所有的静态属性和方法都是线程安全的。

线程安全

如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。

线程安全问题都是由全局变量及静态变量引起的:若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

创建数据库连接

创建连接时需要使用到下面几个类:MongoClient、MongoServer、MongoDatabase、MongoCollection。

MongoClient类

该类是MongoDB服务器的根对象,表示MongoDB的客户端(实例)。数据库的连接是在后台自动进行的(通过使用连接池提高性能)。默认情况下,所有的写操作在服务器承认写之前都是阻塞的。

创建一个MongoClient最简单的方式就是使用Connection String,连接字符串具有如下的模式:

mongodb://[username:[email protected]]hostname[:port][/[database][?options]]

[]表示该项是可选的;当在MongoDB服务器上启用了认证时,需要使用到用户名和密码;当username和database同时使用时,需要保证该用户有操作该数据库的权限;当不匹配时,默认的数据库是admin;如果不知道端口号,则默认端口号为27017。

当需要连接到多台服务器时,不同服务器之间使用”,”分割,且端口号不能省略,如:

mongodb://server1:27017,server1:27018

MongoServer类

使用MongoClient的GetServer()方法可以获取到MongoServer实例,该类的GetDatabase()方法可以根据数据库名获取到MongoDatabase实例。该方法具有如下的重载:

MongoDatabase GetDatabase(MongoDatabaseSettings settings)

MongoDatabase GetDatabase(string databaseName)

MongoDatabase GetDatabase(string databaseName, MongoCredentials credentials)

MongoDatabase GetDatabase(string databaseName, MongoCredentials credentials, WriteConcern writeConcern)

MongoDatabase GetDatabase(string databaseName, WriteConcern writeConcern)

下面的代码演示了如何连接到服务器并获取数据库:

MongoClient client = new MongoClient(); // 连接到本地

MongoServer server = client.GetServer();

MongoDatabase database = server.GetDatabase("test"); // 获取test数据库

MongoDatabase类

通过给定数据库名可以获取到MongoDB上的数据库,进而通过该类的GetCollection()方法根据集合名字获取MongoCollection<TDefaultDocument>实例。

MongoCollection类

通过给定集合名并使用MongoDatabase实例的GetCollection方法获取集合对象,一切的增删改查都是在集合对象的基础上实现的。

插入文档

通过MongoCollection<TDefaultDocument>的Insert<TDefaultDocument>()方法可以插入一个文档。TDefaultDocument可以是默认的BsonDocument类型也可以是用户自定义的类型。若是用户自定义的类型,则该类型中必须有Id字段或属性,或者手动指定主键的名称。

public class Book

{

// int Id{get;set;}

string Author {get;set;}

string Title {get;set;}

}

MongoCollection<Book> books = database.GetCollection<Book>("books"); // 获取集合名为books的集合

Book book = new Book {

Author = "Ernest Hemingway",

Title = "For Whom the Bell Tolls"

};

books.Insert(book);

上述的自定义类型Book中没有定义id字段或属性,插入到集合时或默认给每天记录增加_id键,该键为ObjectId类型。插入时不会报错,但当我们从数据库获取数据并将数据转化为Book类型时,就会出错,原因是Book没有id字段,获取到的_id值不知道往哪里赋值。

批量插入

通过MongoCollection<TDefaultDocument>的InsertBatch ()方法可以进行文档的批量插入。

MongoCollection<BsonDocument> books;

BsonDocument[] batch = {

new BsonDocument {

{ "author", "Kurt Vonnegut" },

{ "title", "Cat‘s Cradle" }

},

new BsonDocument {

{ "author", "Kurt Vonnegut" },

{ "title", "Slaughterhouse-Five" }

}

};

books.InsertBatch(batch);

批量插入比单个插入的效率要高,因为只进行一次连接请求和处理头信息。

上面的插入文档和批量插入演示了MongoDB C#驱动插入数据所支持的两种数据类型。总得来说自定义类型比较方便,而且符合ADO.NET和EF的习惯。但是使用自定义类涉及到序列化的问题,即我们可以控制类中的哪些字段或属性以什么样的规则与集合中的键对应。关于序列化的内容,可以参考官方文档:http://docs.mongodb.org/ecosystem/tutorial/use-csharp-driver/

数据查找方法:FindOne()和FindOneAs <TDefaultDocument>()

FindOne()方法是最简单的查找方法,该方法从集合中返回第一个找到的文档(当集合中有多个文档时,并不能知道会返回哪个文档)。

MongoCollection<Book> books;

Book book = books.FindOne();

FindOneAs <TDefaultDocument>()可以将查找到的文档转换成TdefaultDocument类型:

MongoCollection<Book> books;

BsonDocument document = books.FindOneAs<BsonDocument>();

FindAs <TDefaultDocument>()

这个方法通过查询文档作为参数,告诉服务器应该返回哪个文档。

查询文档是ImongoQuery类型,一般使用其实现类QueryDocument构造查询文档:

MongoCollection collection = database.GetCollection("user");

var query = new QueryDocument("key", "value");

collection.FindAs(typeof(BsonDocument), query);

查询文档的构造也可以通过MongoDB.Driver.Builders.Query进行构造,可以构造等值查询等不同类型的文档:

MongoCollection collection = database.GetCollection("user");

var query = Query.EQ("key", "value");

collection.FindAs(typeof(BsonDocument), query);

Save<TDocument>()

该方法组合了Insert方法和Update方法。当保存的文档中的Id值已存在时,则相当于Update()方法,否则相当于Insert()方法。

MongoCollection<BsonDocument> books;

var query = Query.And(

Query.EQ("author", "Kurt Vonnegut"),

Query.EQ("title", "Cats Craddle")

);

BsonDocument book = books.FindOne(query);

if (book != null) {

book["title"] = "Cat‘s Cradle";

books.Save(book);

}

Save方法的Tdocument类型必须要有Id字段,否则,只能使用Insert方法。

Update()方法

该方法用于更新已经存在的文档。上面使用Save方法进行的更新相当于下面的代码:

MongoCollection<BsonDocument> books;

var query = new QueryDocument {

{ "author", "Kurt Vonnegut" },

{ "title", "Cats Craddle" }

};

var update = new UpdateDocument {

{ "$set", new BsonDocument("title", "Cat‘s Cradle") }

};

BsonDocument updatedBook = books.Update(query, update);

也可以使用Query和Update构造器:

MongoCollection<BsonDocument> books;

var query = Query.And(

Query.EQ("author", "Kurt Vonnegut"),

Query.EQ("title", "Cats Craddle")

);

var update = Update.Set("title", "Cat‘s Cradle");

BsonDocument updatedBook = books.Update(query, update);

FindAndModify()

该方法会将查找到的文档进行修改,一般用于更新单个文档。也可以通过组合查询来匹配多个文档。

var jobs = database.GetCollection("jobs");

var query = Query.And(

Query.EQ("inprogress", false),

Query.EQ("name", "Biz report")

);

var sortBy = SortBy.Descending("priority");

var update = Update.

.Set("inprogress", true)

.Set("started", DateTime.UtcNow);

var result = jobs.FindAndModify(

query,

sortBy,

update,

true // return new document

);

var chosenJob = result.ModifiedDocument;

MapReduce()

Map/Reduce是一种从集合中聚合数据的方法。集合中的每个文档都会被传递到map函数,即emit,来产生中间值。而中间值会被传递到reduce函数进行聚合操作。

var map =

"function() {" +

" for (var key in this) {" +

" emit(key, { count : 1 });" +

" }" +

"}";

var reduce =

"function(key, emits) {" +

" total = 0;" +

" for (var i in emits) {" +

" total += emits[i].count;" +

" }" +

" return { count : total };" +

"}";

var mr = collection.MapReduce(map, reduce);

foreach (var document in mr.GetResults()) {

Console.WriteLine(document.ToJson());

}

其他的属性和方法

MongoCursor<TDocument>类:Find方法并不会立即的返回结果,而是返回一个能够枚举结果的游标;查询也不会立即的被发送到服务器上,而是在试图接收第一个结果时,才会被服务器处理。

枚举游标:通过foreach来枚举游标所指向的结果:

var query = Query.EQ("author", "Ernest Hemingway");

var cursor = books.Find(query);

foreach (var book in cursor) {

}

也可通过LINQ的拓展方法来枚举游标:

var query = Query.EQ("author", "Ernest Hemingway");

var cursor = books.Find(query);

var firstBook = cursor.FirstOrDefault();

var lastBook = cursor.LastOrDefault();

上面的方式,查询会被发送到服务器2次FirstOrDefault一次、LastOrDefault一次。

注意:当游标遍历完之后要记得释放(调用Dispose()方法)。

在枚举之前修改游标:在枚举游标之前可以修改游标的属性,有两种方式可以修改,一种是直接修改,另一种是通过Fluent接口设置属性。

// 跳过游标的前100条记录并只处理10条记录

var query = Query.EQ("status", "pending");

var cursor = tasks.Find(query);

cursor.Skip = 100;

cursor.Limit = 10;

foreach (var task in cursor) {

}

上面的实现也可以用下面的方式:

var query = Query.EQ("status", "pending");

foreach (var task in tasks.Find(query).SetSkip(100).SetLimit(10)) {

// do something with task

}

游标中可修改的属性:BatchSize、Fields 、Flags 、Limit 、Options 、SerializationOptions 、Skip、SlaveOk

其他的方法:Clone、Count、Explain、Size

WriteConcern类:新增、保存、更新和删除操作是否成功,查询操作可根据返回的查询结果判定(是否为空)。

Insert()返回WriteConcernResult其中比较重要的属性有:HasLastErrorMessage、LastErrorMessage、Response

Update()也返回WriteConcernResult其中DocumentsAffected表示被更新的文档数。UpdatedExisting表示是否有更新,其他的基本一致。

Save()和Remove()方法返回的WriteConcernResult与Update()一致。

为查找设置超时时间:collection.FindAll().SetMaxTime(TimeSpan.FromSeconds(1));当超过1秒钟,则查询会被中止。

批量操作(批量新增、更新、删除)

有两种方式可以进行批量操作,一种是对操作顺序执行,并返回第一个出错时的信息;一种是对操作并非执行,并返回所有出错的信息。

顺序执行的批量操作:

BulkWriteOperation bulk = collection.InitializeOrderedBulkOperation();

bulk.Insert(new BsonDocument("_id", 1));

bulk.Insert(new BsonDocument("_id", 2));

bulk.Insert(new BsonDocument("_id", 3));

bulk.Insert(new BsonDocument("_id", 4));

bulk.Find(Query.EQ("_id", 1)).Update(Update.Set("name", "wangdh1"));

bulk.Find(Query.EQ("_id", 2)).Remove();

bulk.Find(Query.EQ("_id", 3)).ReplaceOne(new BsonDocument("_id", 3).Add("name", "wangdh3"));

BulkWriteResult bulkResult = bulk.Execute();

并行执行的批量操作:

BulkWriteOperation bulk = collection.InitializeUnorderedBulkOperation();

bulk.Find(Query.EQ("_id", 1)).RemoveOne();

bulk.Find(Query.EQ("_id", 2)).RemoveOne();

BulkWriteResult bulkResult = bulk.Execute();

批量操作的返回值:BulkWriteResult

重要属性有:DeletedCount、InsertedCount、ModifiedCount、MatchedCount、ProcessedRequests分别表示删除、插入、更新、查找到的数量以及处理过程中产生的请求。

基础类:BSON命名空间

BSON类库是C#驱动的基础,处理的细节包括:I/O、序列化和BSON文档的内存对象模型。重要的BSON对象模型有:BsonType、BsonValue、BsonElement、BsonDocument、BsonArray.

BsonType:表示Bson的类型,是枚举类型。

BsonValue:Bson的value的抽象表示

BsonElement:是一个name/value表示的键值对类型

BsonDocument:是BsonElement(键值对)集合

创建内嵌的 BsonDocument:

BsonDocument nested = new BsonDocument {

{ "name", "John Doe" },

{ "address", new BsonDocument {

{ "street", "123 Main St." },

{ "city", "Centerville" },

{ "state", "PA" },

{ "zip", 12345}

}}

};

处理BsonDocument:既然BsonDocument是键值对集合,即可通过键名获取对应的值,再通过AsXXX方法将获取到的值转换为相应的类型。

BsonDocument book;

string author = book["author"].AsString;

DateTime publicationDate = book["publicationDate"].AsDateTime;

int pages = book["pages", -1].AsInt32;

BsonArray:Bson数组

时间: 2024-11-10 11:20:40

[转]MongoDB学习 C#驱动操作MongoDB的相关文章

MongoDB学习笔记一:MongoDB的下载和安装

趁着这几天比较空闲,准备学习一下MongoDB数据库,今天就简单的学习了一些MongoDB的下载和安装,并创建了存储MongoDB的数据仓库.将自己今天学习到的写成博客分享给大家. 一.MongoDB的下载和安装 MongoDB的下载地址为:http://www.mongodb.org/ 1.进入官网的首页后,在首页的右上方单击Downloads连接,如图所示: 2.在页面中可以看到目前最新的版本和以前发布过的版本,这里选择最新版本,windows 32位的进行下载,文件的格式为ZIP格式的,单

MongoDB快速入门学习笔记8 MongoDB的java驱动操作

import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.FindIterable;

在C#中使用官方驱动操作MongoDB

MongoDB的官方驱动下载地址:https://github.com/mongodb/mongo-csharp-driver/releases 目前最新的版本是2.10,支持.NET 4.5以上.由于我现在的程序还在.NET4.0上面构建,所以这里使用1.10.1版本. 添加引用 解压下载到的驱动,然后在我们的程序中添加引用: MongoDB.Bson.dll MongoDB.Driver.dll 然后在代码中添加Using: using MongoDB.Bson; using MongoDB

golang学习之mgo操作mongodb

mgo是mongodb的golang驱动,测试代码: // mgotest project main.go package main import ( "fmt" "time" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) type User struct { Id bson.ObjectId `bson:"_id"` Username string `bson:&q

【MongoDB学习笔记2】MongoDB基本知识

1.MongoDB的数据基本称为文档,类似关系数据库的中的行: 2.类似,集合(Collection)是动态模式(dynamic schame)的表: 3.MongoDB的实例可以有多个相互独立的数据库,没有数据库中包含多个集合: 4.每个文档都有一个键,这个键在所在的集合中是唯一的: 5.MongoDB自带一个JavaScript Shell,用来管理MongoDB实例和数据操作: 一.文档和键 文档数据表达类似哈希或者字典,例如: {"geeting":"hello wo

MongoDB学习笔记(1):MongoDB简介

1. MongoDB的特点: (1) 易于使用 MongoDB是一个面向文档的数据库,非关系型数据库.通过在文档中嵌入式文档和数据,面向对象的方法能够仅使用一条记录来表现复杂的层次关系.文档的键和值不再是固定的类型和大小. (2) 易于扩展 MongoDB的设计采用横向扩展,即通过分区将数据分散到更多机器上.面向文档的数据模型使它很容易地在多台服务器之间进行数据分割.MongoDB能够自动处理集群的数据和负载,自动重新分配文档,以及将用户请求路由到正确的机器上. (3) 丰富的功能 1) 索引

【MongoDB学习笔记31】MongoDB配置副本集

一.配置环境 1.两台安装了mongodb的CentOS服务器;(安装参考http://281816327.blog.51cto.com/907015/1598270) 2.两台服务器的ip分别为192.168.1.112.192.168.1.113: 3.两台服务器防火墙放开mongodb的默认27017的端口: 二.配置服务器 两台服务器都做如下的配置 创建/data/db文件夹 mkdir /date && mkdir /data/db 修改配置文件 vim /etc/mongodb

MongoDB学习比较-07 C#驱动操作MongoDB

下载驱动 驱动的下载有两种方式:一种是在C#项目中通过NuGet进行安装,另一种是通过下面的链接:https://github.com/mongodb/mongo-csharp-driver/releases 直接下载msi进行安装或zip压缩包.不管哪种方式,其主要的目的都是获取两个dll文件:MongoDB.Bson.dll.MongoDB.Driver.dll.这是在程序中需要引用的两个类库文件. .NET版本要求 目前最新版的C#驱动是1.9.2,是在 .NET3.5的基础上构建的,所以

mongodb学习(Document数据操作)

这篇博文主要学习mongodb中的Document的数据更新操作.包括了数据的"插入","更新"和"删除". Document数据插入 插入一条数据到document文档中用到的命令是"db.集合名称.insert(on=bj)" ,如图: 从图中可以看出在我插入一条数据之后,再次查询发现确实添加到集合中了. 那么如果我需要批量插入数据应该怎么操作呢??我们在之前已经说过了,mongodb的客户端shell实际上就是一个Jav