文章目錄
斷斷續續寫了個關於MongoDB的簡單樣本,涉及到了基礎的CRUD。實踐的過程中,發現不少問題,尤其是新舊版本的C#驅動類庫變動較大,所以有一些明顯的問題自己還是摸不著頭腦,記錄下來,期待您的指點。
一、開發環境搭建
這個不用多廢話了,可以搜尋一下,有很多文章已經介紹了如何搭建開發環境。如果您想親自嘗試一下,參考官方文檔的這一篇,按照說明一步一步自己在本地配置一個可開發MongoDB應用程式的windows環境。當然了,如果您的環境不是windows,可以選擇這裡的文檔,對照設定即可。
二、實體類說明
在demo中,您可以看到一個簡單的實體類Book,其中包含四個屬性:
using System;namespace SimpleMongoDBApp{ using MongoDB.Bson; [Serializable] public class Book { public Book() { } public Book(string author, string title, DateTime createDate) { this.Author = author; this.Title = title; this.CreateDate = createDate; } public string Author { get; set; } public string Title { get; set; } public DateTime CreateDate { get; set; } /// <summary> /// 主鍵 /// </summary> public ObjectId Id { get; set; } }}
需要您注意的是主鍵Id屬性的類型是ObjectId。在增刪改查中,這個Id的作用是非常重要的。
三、簡單的CRUD
老實說,這沒什麼可說的,只是簡單類庫調用而已,但是實踐的時候還是有一些小意外,感覺和文檔說明的不一致。這裡的樣本主要是參考這一篇而成的。
1、增刪改
這三個相對容易一些,對照文檔說明,調用對應的幾個方法,即可完成增刪改的操作。比如對於簡單的更新方法:
public void Update(Book query, Book dest) { string connectionString = Config.GetCurrentMongoDBConnString(); MongoServer server = MongoServer.Create(connectionString); MongoDatabase database = server.GetDatabase(Config.CurrentDBName); using (server.RequestStart(database)) { MongoCollection<Book> books = database.GetCollection<Book>(Config.CurrentTbName); QueryDocument condition = new QueryDocument("_id", query.Id);//按照id更新 Book book = books.FindOne(condition); if (book != null) { dest.Id = query.Id; books.Save<Book>(dest); } } }
這裡我使用的是Save函數,我們也可以調用文檔說明中的Update方法,最終效果其實是一樣的。
2、分頁查詢
和關係型資料庫一樣,查詢也可以分很多種,比如精確匹配,範圍查詢,模糊比對,分組查詢等等。本文的樣本只是進行了簡單的按欄位精確匹配,是最簡單的一種查詢。好在現在的類庫都有對應的查詢方法,您可以自己嘗試不同種類的複雜查詢試試看。對於簡單的查詢直接調用相關Find方法即可,分頁查詢我們通常通過SetSkip和SetLimit配合使用返回查詢結果:
/// <summary> /// 分頁查詢 /// </summary> public IList<Book> Select(int currentPage, int recordsPerPage, Book query) { List<Book> listResult = new List<Book>(); string connectionString = Config.GetCurrentMongoDBConnString(); MongoServer server = MongoServer.Create(connectionString); MongoDatabase database = server.GetDatabase(Config.CurrentDBName); MongoCollection<Book> books = database.GetCollection<Book>(Config.CurrentTbName); QueryComplete condition = Query.And(Query.EQ("Title", query.Title));//有查詢結果 //QueryComplete condition = Query.And(Query.EQ("Author", query.Author));//無查詢結果 //QueryComplete condition = Query.And(Query.EQ("Title", query.Title), Query.EQ("Author", query.Author));//無查詢結果 MongoCursor<Book> cursors = books.Find(condition).SetSkip((currentPage - 1) * recordsPerPage).SetLimit(recordsPerPage);// books.Find(condition); //MongoCursor<Book> cursors = books.FindAs<Book>(condition).SetSkip((currentPage - 1) * recordsPerPage).SetLimit(recordsPerPage);// books.Find(condition); //MongoCursor<Book> cursors = books.FindAll().SetSkip((currentPage - 1) * recordsPerPage).SetLimit(recordsPerPage);// books.Find(condition); listResult.AddRange(cursors); return listResult; }
實踐的時候我發現一個問題,就是在嘗試按照Author屬性進行查詢的時候,一條記錄沒有(實際匹配結果應該不止一條,而且比按照Title查詢的匹配結果更多),但是按照Title資料又可以查詢出結果,對照文檔尋找良久,沒有找到原因,莫非又是….傳說中的rp問題?鬱悶。
四、老趙的EasyMongo
對於MongDB的其他相關方法,可以參考官方說明文檔,類庫已經非常豐富。到這裡您可能已經發現了一個問題,就是我在調用MongoDB相關類庫方法的時候,重複的代碼較多,比如下面這一段:
string connectionString = Config.GetCurrentMongoDBConnString(); MongoServer server = MongoServer.Create(connectionString); MongoDatabase database = server.GetDatabase(Config.CurrentDBName); using (server.RequestStart(database)) { //some code here }
就出現不少次,那什麼,大家當然想到要重構,要使用ORM,要更優雅地調用……等等等等。我當然已經發現程式中的問題,本來想自己再封裝一層的,讓調用更簡潔舒服一些,但是自從看到了老趙的EasyMongo(原來這麼強大實用的東西牛人早幫我們做好了,看了一下源碼,感覺和他之前的FastReflection差不多複雜,我承認自己真的寫不出來),還是直接推薦使用了吧。
最後介紹一個國內非常好的NoSQL學習資源:
http://blog.nosqlfan.com/
demo下載:MongoDBApp