如何在 Windows 上安裝 MongoDB
MongoDB C# Driver 管理快速入門指南
這是MongoDB driver的第一部分威鹿。在這一部分民效,你可以看到如何去執(zhí)行一些數(shù)據(jù)庫的基本CRUD(C-創(chuàng)建控乾,R-讀取,U-更新,D-刪除)操作。
連接
以下展示了三種連接到MongoDB遠(yuǎn)程服務(wù)器和本地服務(wù)器的方式 :
// 連接到單實例MongoDB服務(wù)
// 這種連接方式不會自動檢測連接的節(jié)點是主節(jié)點還是復(fù)制集的成員節(jié)點
var client = new MongoClient();
// 或者使用string連接本地服務(wù)器,localhost=127.0.0.1,連接到單實例
var client = new MongoClient("mongodb://localhost:27017");
// 連接到復(fù)制集(多節(jié)點)
var client = new MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019");
客戶端實例現(xiàn)在可以擁有連接到連接字符串中指定的服務(wù)器或服務(wù)器的連接池哄酝。
MongoClient
MongoClient
實例實際上表示一個連接數(shù)據(jù)庫的連接池;
你僅僅只需要一個MongoClient
類實例祷膳,即使在多線程情況下陶衅;
標(biāo)注:
實際上,你只需要為給定的集群創(chuàng)建一個MongoClient實例直晨,并在應(yīng)用程序中使用它搀军。但是,如果連接字符串是相同的勇皇,那么創(chuàng)建多個MongoClient將仍然共享相同的連接池罩句。
Get a Database
獲取一個數(shù)據(jù)庫實例,列舉數(shù)據(jù)庫的名稱可以通過client
中的GetDatabase
方法儒士,在數(shù)據(jù)庫存在的情況下的止,該方式都是可行的。它將在首次被調(diào)用時創(chuàng)建着撩。
var database = client.GetDatabase("foo");
現(xiàn)在诅福,database
變量保存了對數(shù)據(jù)庫“foo”的引用.
Get a Collection
獲取一個集合實例,列舉集合的名稱可以通過database
中GetCollection<TDocument>.在集合存在的情況下拖叙,它將在首次被調(diào)用時創(chuàng)建氓润。
var collection = database.GetCollection<BsonDocument>("bar");
現(xiàn)在,collection
變量保存了對數(shù)據(jù)庫“foo”下“bar”集合的引用.
標(biāo)注:
泛型參數(shù)TDocument表示集合中存在的模式薯鳍,使用一個BsonDocument來表示沒有預(yù)定的模式咖气。
Insert a Document
一旦你擁有了collection
實例,你就可以插入一個文檔到集合中挖滤。例如崩溪,考慮下面的JSON文檔,它是一個包含了一個字段信息的嵌入式文檔斩松。
{
"name": "MongoDB",
"type": "database",
"count": 1,
"info": {
x: 203,
y: 102
}
}
你可以使用.NET driver中的BsonDocument類創(chuàng)建這個文檔伶唯,方式如下:
var document = new BsonDocument
{
{ "name", "MongoDB" },
{ "type", "Database" },
{ "count", 1 },
{ "info", new BsonDocument
{
{ "x", 203 },
{ "y", 102 }
}
}
};
把這個文檔插入到集合中,可以是使用InsertOne
或者InsertOneAsync
方法
collection.InsertOne(document);//同步
await collection.InsertOneAsycn(document);//異步
標(biāo)注:
.NET driver 當(dāng)前已全部支持異步操作惧盹。關(guān)于更多的async和await的信息乳幸,參見MSDN documentation
https://msdn.microsoft.com/en-us/library/hh191443.aspx
驅(qū)動中所有的API都已經(jīng)同時支持同步和異步.
Insert Multiple Documents
插入多條數(shù)據(jù)到數(shù)據(jù)庫,可以使用InsertMany
或者InsertManyAsync
兩種方式.
// 生成 100 個counter從0~99遞增的文檔
var documents = Enumerable.Range(0, 100).Select(i => new BsonDocument("counter", i));
插入數(shù)據(jù)
collection.InsertManh(documnets);
await collection.InsertManyAsycn(documents);
Counting Documents
現(xiàn)在钧椰,我們插入了101個文檔到數(shù)據(jù)庫里面(100在循環(huán)中粹断,首次插入1),我們可以核查這些數(shù)據(jù),如果我們使用Count
或者CountAsycn
方法. 下面的代碼應(yīng)該可以使得count
的值為101.
var count = collection.Count(new BsonDocument());
or
var count = await collection.CountAsync(new BsonDocument());
標(biāo)注:
空的BsonDocument參數(shù)是一個過濾器嫡霞。在這里瓶埋,指的是要計算所有的文檔.
Query the Collection
使用Find
方法去集合中查詢. 該方法會返回一個IFindFluent<TDocument, TProjection> 實例,它提供一個接口鏈接find操作設(shè)置.
Find the First Document in a Collection
調(diào)用FirstOrDefault 或者FirstOrDefaultAsync 方法,可以獲取集合的第一個文檔.FirstOrDefault
返回第一個文檔或者null. 當(dāng)你只需要一個匹配的文檔或只對第一個文檔感興趣時悬赏,該方法非常有用.
下面的例子將會打印出再集合中查詢出來的第一個文檔:
var document = collection.Find(new BsonDocument()).FirstOrDefault();
Consloe.WriteLine(document.ToString());
var document = await collection.Find(new BsonDocument()).FirstOrDefaultAsync();
Console.WriteLine(document.ToString());
該例子將會打印出以下內(nèi)容:
{
"_id": ObjectId("5940f2b98198abd6a5eea7b1") },
"name": "MongoDB",
"type": "database",
"count": 1,
"info": { "x" : 203, "y" : 102 }
}
元素 “id” 為 MongoDB 數(shù)據(jù)庫自動添加到文檔中狡汉,這是打印出來的內(nèi)容與插入的內(nèi)容不一致的原因。MongoDB數(shù)據(jù)庫內(nèi)部保留所有以
“_”
和“$”
開頭的字段名稱.
Find All Documents in a Collection
使用ToList
或者ToListAsycn
方法可以檢索到集合中的所有文檔闽颇,當(dāng)需要返回的文檔比較少量時盾戴,該方法非常有用.
var documents = collection.Find(new BsonDocument()).ToList();
var documents = await collection.Find(new BsonDocument()).ToListAsync();
如果返回的文檔數(shù)量比預(yù)期的大,可以使用通過迭代的方式進(jìn)行處理兵多。ForEachAsync
將會為每個返回的文檔調(diào)用一個回調(diào)尖啡。
await collection.Find(new BsonDocument()).ForEachAsync(d => Console.WriteLined(d));
如果使用的是同步的API,則要使用C#中的ToEnumerable
抽象方法去迭代每個文檔:
var cursor = collection.Find(new BsonDocument()).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
Console.WriteLine(document);
}
上面的例子將會打印出相同的信息剩膘。更多的信息參見reference documention
Get a Single Document With a Filter
在一個集合中衅斩,我們可以創(chuàng)建一個篩選器傳遞給Find
方法去獲取一個文檔的子集。例如怠褐,如果我們想查找“i”字段的值為71的文檔畏梆,我們可以使用如下的方式:
var filter = Builders<BsonDocument>.Filter.Eq("i", 71);
var document = collection.Find(filter).First();
Console.WriteLine(document);
var document = await collection.Find(filter).FirstAsync();
Console.WriteLine(document);
以上應(yīng)該僅打印出一個文檔:
{ "_id" : ObjectId("5515836e58c7b4fbc756320b"), "i" : 71 }
標(biāo)注:
使用
Filter
,Sort
和Projection
以簡單和簡潔的方式創(chuàng)建一個查詢.
Get a Set of Documents With a Filter
我們也可以從集合中獲取一組文檔奈懒。例如奠涌,如果我們獲取所有符合 i > 50 條件的文檔,可以使用如下的方式:
var filter = Builders<BsonDocument>.Filter.Gt("i", 50);// Gt表示大于
var cursor = collection.Find(filter).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
Console.WriteLine(document);
}
await collection.Find(filter).ForEachAsync(document => Console.WriteLine(document));
還可以限定一個范圍查詢磷杏,例如 50 < i <= 100;
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Gt("i", 50) & filterBuilder.Lte("i", 100);//Lt表示小于溜畅,Lte表示小于等于
var cursor = collection.Find(filter).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
Console.WriteLine(document);
}
await collection.Find(filter).ForEachAsync(document => Console.WriteLine(document));
Sorting Documents
我們可以通過調(diào)用 Sort
方法來創(chuàng)建一個排序匹配查詢。在現(xiàn)有的 filter
構(gòu)造方法下极祸,我們可以使用 Descending
建立一個降序構(gòu)造器來排序我們的文檔:
var filter = Builders<BsonDocument>.Filter.Exists("i");
var sort = Builders<BsonDocument>.Sort.Descending("i");
var document = collection.Find(filter).Sort(sort).First();
var document = await collection.Find(filter).Sort(sort).FirstAsync();
Projecting Fields(映射字段)
很多時候慈格,我們不需要文檔中包含的所有字段,Projection
構(gòu)造器可以在一個查詢操作中構(gòu)造映射字段遥金。下面的例子中浴捆,我們排除了“_id”字段,并且輸出第一個匹配的文檔:
var projection = Builders<BsonDocument>.Projection.Exclude("_id");
var document = collection.Find(new BsonDocument()).Project(projection).First();
Console.WriteLine(document.ToString());
var document = await collection.Find(new BsonDocument()).Project(projection).FirstAsync();
Console.WriteLine(document.ToString());
Updating Documents
MongoDB 支持多種更新操作方式
更新最多一個文檔(如果沒有匹配篩選器稿械,可能為零個文檔)选泻,使用UpdateOne或者UpdateOneAsync去指定篩選器并更新匹配的文檔。下面溜哮,我們更新篩選器為 i == 10 匹配的第一個文檔,并將該文檔 i 的值更新為110:
var filter = Builders<BsonDocument>.Filter.Eq("i", 10);
var update = Builders<BsonDocument>.Update.Set("i", 110);
collection.UpdateOne(filter, update);
await collection.UpdateOneAsync(filter, update);
更新篩選器匹配的所有文檔色解,使用UpdateMany或者UpdateManyAsync方法茂嗓。下面例子,將把所有 i < 100 匹配的文檔中 i 的值增加 100科阎。
var filter = Builders<BsonDocument>.Filter.Lt("i", 100);
var update = Builders<BsonDocument>.Update.Inc("i", 100);// Inc操作符表示:給i字段增加某個大小的值
var result = collection.UpdateOne(filter, update);
if (result.IsModifiedCountAvailable)
{
Console.WriteLine(result.ModifiedCount);
}
var result = await collection.UpdateOneAsync(filter, update);
if (result.IsModifiedCountAvailable)
{
Console.WriteLine(result.ModifiedCount);
}
更新方法返回的結(jié)果為UpdateResult述吸,它提供關(guān)于該操作的信息,包括更新后修改的文檔的數(shù)量。
標(biāo)注:
根據(jù)MongoDB數(shù)據(jù)庫的版本蝌矛,某些特性可能無法使用道批。在這些情況下,我們已經(jīng)嘗試了檢查是否有能力檢查它們的可用性入撒。
Deleting Documents
刪除最多一個文檔(如果沒有匹配篩選器隆豹,可能為零個文檔),使用 DeleteOne 或者 DeleteOneAsync方法:
var filter = Builders<BsonDocument>.Filter.Eq("i", 110));
collection.DeleteOne(filter);
await collection.DeleteOneAsync(filter);
刪除篩選器匹配的所有文檔茅逮,使用DeleteMany 或者 DeleteManyAsync 方法璃赡。下面是刪除所有 i >= 100 匹配的文檔:
var filter = Builders<BsonDocument>.Filter.Gte("i", 100));// Gte表示大于等于
var result = collection.DeleteMany(filter);
Console.WriteLine(result.DeletedCount);
var result = await collection.DeleteManyAsync(filter);
Console.WriteLine(result.DeletedCount);
刪除方法返回的結(jié)果為DeleteResult ,它提供關(guān)于該操作的信息献雅,包括刪除的文檔數(shù)量碉考。
Bulk Writes (批量操作)
Bulk 操作有兩種類型:
- 有序Bulk操作
以有序的方式執(zhí)行所有的操作,并且在首次遇到異常時拋出異常挺身。
- 無序Bulk操作
執(zhí)行所有的操作侯谁,并記錄操作過程中的全部異常。無序的批量操作不能保證執(zhí)行的順序章钾。
讓我們看一看下面的兩個關(guān)于有序和無序的操作例子:
var models = new WriteModel<BsonDocument>[]
{
new InsertOneModel<BsonDocument>(new BsonDocument("_id", 4)),
new InsertOneModel<BsonDocument>(new BsonDocument("_id", 5)),
new InsertOneModel<BsonDocument>(new BsonDocument("_id", 6)),
new UpdateOneModel<BsonDocument>(
new BsonDocument("_id", 1),
new BsonDocument("$set", new BsonDocument("x", 2))),
new DeleteOneModel<BsonDocument>(new BsonDocument("_id", 3)),
new ReplaceOneModel<BsonDocument>(
new BsonDocument("_id", 3),
new BsonDocument("_id", 3).Add("x", 4))
};
// 1. 有序的批量操作 - 保證操作的順序
collection.BulkWrite(models);
// 2. 無序的批量操作 - 無法保證操作的順序
collection.BulkWrite(models, new BulkWriteOptions { IsOrdered = false });
異步
// 1. 有序的批量操作 - 保證操作的順序
await collection.BulkWriteAsync(models);
// 2. 無序的批量操作 - 無法保證操作的順序
await collection.BulkWriteAsync(models, new BulkWriteOptions { IsOrdered = false });
重要:
批量操作功能在MongoDB數(shù)據(jù)庫版本為2.6及之前的版本不被推薦使用墙贱,在性能上有較大的影響。