如何在 Windows 上安裝 MongoDB
MongoDB C# Driver 管理快速入門指南
這是MongoDB driver的第一部分。在這一部分,你可以看到如何去執行一些數據庫的基本CRUD(C-創建,R-讀取,U-更新,D-刪除)操作。
連接
以下展示了三種連接到MongoDB遠程服務器和本地服務器的方式 :
// 連接到單實例MongoDB服務
// 這種連接方式不會自動檢測連接的節點是主節點還是復制集的成員節點
var client = new MongoClient();
// 或者使用string連接本地服務器,localhost=127.0.0.1,連接到單實例
var client = new MongoClient("mongodb://localhost:27017");
// 連接到復制集(多節點)
var client = new MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019");
客戶端實例現在可以擁有連接到連接字符串中指定的服務器或服務器的連接池。
MongoClient
MongoClient
實例實際上表示一個連接數據庫的連接池;
你僅僅只需要一個MongoClient
類實例,即使在多線程情況下;
標注:
實際上,你只需要為給定的集群創建一個MongoClient實例,并在應用程序中使用它。但是,如果連接字符串是相同的,那么創建多個MongoClient將仍然共享相同的連接池。
Get a Database
獲取一個數據庫實例,列舉數據庫的名稱可以通過client
中的GetDatabase
方法,在數據庫存在的情況下,該方式都是可行的。它將在首次被調用時創建。
var database = client.GetDatabase("foo");
現在,database
變量保存了對數據庫“foo”的引用.
Get a Collection
獲取一個集合實例,列舉集合的名稱可以通過database
中GetCollection<TDocument>.在集合存在的情況下,它將在首次被調用時創建。
var collection = database.GetCollection<BsonDocument>("bar");
現在,collection
變量保存了對數據庫“foo”下“bar”集合的引用.
標注:
泛型參數TDocument表示集合中存在的模式,使用一個BsonDocument來表示沒有預定的模式。
Insert a Document
一旦你擁有了collection
實例,你就可以插入一個文檔到集合中。例如,考慮下面的JSON文檔,它是一個包含了一個字段信息的嵌入式文檔。
{
"name": "MongoDB",
"type": "database",
"count": 1,
"info": {
x: 203,
y: 102
}
}
你可以使用.NET driver中的BsonDocument類創建這個文檔,方式如下:
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);//異步
標注:
.NET driver 當前已全部支持異步操作。關于更多的async和await的信息,參見MSDN documentation
https://msdn.microsoft.com/en-us/library/hh191443.aspx
驅動中所有的API都已經同時支持同步和異步.
Insert Multiple Documents
插入多條數據到數據庫,可以使用InsertMany
或者InsertManyAsync
兩種方式.
// 生成 100 個counter從0~99遞增的文檔
var documents = Enumerable.Range(0, 100).Select(i => new BsonDocument("counter", i));
插入數據
collection.InsertManh(documnets);
await collection.InsertManyAsycn(documents);
Counting Documents
現在,我們插入了101個文檔到數據庫里面(100在循環中,首次插入1),我們可以核查這些數據,如果我們使用Count
或者CountAsycn
方法. 下面的代碼應該可以使得count
的值為101.
var count = collection.Count(new BsonDocument());
or
var count = await collection.CountAsync(new BsonDocument());
標注:
空的BsonDocument參數是一個過濾器。在這里,指的是要計算所有的文檔.
Query the Collection
使用Find
方法去集合中查詢. 該方法會返回一個IFindFluent<TDocument, TProjection> 實例,它提供一個接口鏈接find操作設置.
Find the First Document in a Collection
調用FirstOrDefault 或者FirstOrDefaultAsync 方法,可以獲取集合的第一個文檔.FirstOrDefault
返回第一個文檔或者null. 當你只需要一個匹配的文檔或只對第一個文檔感興趣時,該方法非常有用.
下面的例子將會打印出再集合中查詢出來的第一個文檔:
var document = collection.Find(new BsonDocument()).FirstOrDefault();
Consloe.WriteLine(document.ToString());
var document = await collection.Find(new BsonDocument()).FirstOrDefaultAsync();
Console.WriteLine(document.ToString());
該例子將會打印出以下內容:
{
"_id": ObjectId("5940f2b98198abd6a5eea7b1") },
"name": "MongoDB",
"type": "database",
"count": 1,
"info": { "x" : 203, "y" : 102 }
}
元素 “id” 為 MongoDB 數據庫自動添加到文檔中,這是打印出來的內容與插入的內容不一致的原因。MongoDB數據庫內部保留所有以
“_”
和“$”
開頭的字段名稱.
Find All Documents in a Collection
使用ToList
或者ToListAsycn
方法可以檢索到集合中的所有文檔,當需要返回的文檔比較少量時,該方法非常有用.
var documents = collection.Find(new BsonDocument()).ToList();
var documents = await collection.Find(new BsonDocument()).ToListAsync();
如果返回的文檔數量比預期的大,可以使用通過迭代的方式進行處理。ForEachAsync
將會為每個返回的文檔調用一個回調。
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
在一個集合中,我們可以創建一個篩選器傳遞給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);
以上應該僅打印出一個文檔:
{ "_id" : ObjectId("5515836e58c7b4fbc756320b"), "i" : 71 }
標注:
使用
Filter
,Sort
和Projection
以簡單和簡潔的方式創建一個查詢.
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
我們可以通過調用 Sort
方法來創建一個排序匹配查詢。在現有的 filter
構造方法下,我們可以使用 Descending
建立一個降序構造器來排序我們的文檔:
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
構造器可以在一個查詢操作中構造映射字段。下面的例子中,我們排除了“_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);
}
更新方法返回的結果為UpdateResult,它提供關于該操作的信息,包括更新后修改的文檔的數量。
標注:
根據MongoDB數據庫的版本,某些特性可能無法使用。在這些情況下,我們已經嘗試了檢查是否有能力檢查它們的可用性。
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);
刪除方法返回的結果為DeleteResult ,它提供關于該操作的信息,包括刪除的文檔數量。
Bulk Writes (批量操作)
Bulk 操作有兩種類型:
- 有序Bulk操作
以有序的方式執行所有的操作,并且在首次遇到異常時拋出異常。
- 無序Bulk操作
執行所有的操作,并記錄操作過程中的全部異常。無序的批量操作不能保證執行的順序。
讓我們看一看下面的兩個關于有序和無序的操作例子:
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數據庫版本為2.6及之前的版本不被推薦使用,在性能上有較大的影響。