.net Mongo Driver 1.0與2.0的對比與2.0的優化


前言

  最近閑的時間有點多,所以還是寫博客吧。

  有人說Mongo 2.0的寫法難以把控,好多地方不知道咋用,所以堅持用1.0(不願意去嘗試2.0),我感覺不可理解。所以寫篇博客比較下。

  Mongo C#驅動1.0到2.0設計方面的差別非常大。

正文

先說1.0吧,更像是Mongo 各功能的直譯,所以寫法與mongo原生查詢修改等比較類似,易上手。但是設計上確實存在很多問題。簡單說幾點:


 

a.在query的構建方面,雖然有問題,但是勉強能接受

1  var modelCursor = collection.Find(
2                 Query.And(Query.Matches("Name", "test"),Query.EQ("Age",10),Query.In("id",new BsonArray(){"123","456","sda"})));
3 var modelCursor1 = collection.Find(
4                Query.And(Query<TestData>.Matches(t => t.Name, "test"), Query<TestData>.EQ(t=>t.Age, 10), Query<TestData>.In(t=>t._id, new BsonArray() { "123", "456", "sda" })));

第一種方式代碼簡單,但是硬字符串比較多,萬一改個字段,維護難度大

第二種方式代碼維護性好,但是代碼真是煩瑣,每個query都要來個泛型約定,冗余太多了

 

b.大量linq方法與數據庫中執行構建查詢的方法混在一起,這點是可以改進的。否則可能出現一下問題:

在查詢返回類型上MongoCursor<TDefaultDocument>。繼承IEnumerable<T>,Find時只是構建查詢而已,只有調用GetEnumerator()才回去數據庫查詢數據。也就是ToList()或者foreach的時候才去查詢。這一點設計的沒錯跟ef一致的

執行方式,看看源碼截圖:

 

 

這樣看起來沒問題,但是在使用時,如下代碼:

這是段常用的分頁代碼,我天真的以為他會將cursor.Skip().Take()生成查詢去數據庫中執行再把200條結果返回給我。但是實際情況不是這樣的

其實已經把所有數據都拿出來了,只是在客戶端使用了linq的Skip去跳過而已。

正確的用法是:

要使用cursor的Set開頭的方法才是構建查詢的。

如果你學ef那也學徹底點啊,不信你看ef查詢時的Skip

人家把Skip Take都“重寫”了好吧,根本沒使用IEnumerable<T>的Skip。這一點想說明的,就是導致了大量的linq客戶端執行的代碼與Mongo服務端執行的代碼混雜的問題

 

 

c.另外分組查詢是設計非常不好的。比如:

      

請看GroupArgs的注釋:

知道我寫這么多注釋,為啥嗎,我怕過兩天我也不知道咋用的了。更別說讓其他同事用了。一個分組查詢居然還要在c#中寫原始的js代碼來實現。所以驅動在這里的實現只是半成品的。

 

 

對比着再說說2.0吧,首先與時俱進大量采用了異步編程。然后對lamda表達式與強類型的支持都做了改進。


 

a.首先查詢全部是lamda表達式了,這次算是把查詢這塊徹底本地化了。不用再去記住Mongo查詢原生的語法了,門檻很低了。如:

b.重寫了查詢返回值類型,叫什么FindFluent。翻譯過來就是可鏈式調用的東東,看看源碼:

 

果然都是返回的this便於鏈式調用,再看看里面的方法:

 

2.0不再繼承IEnumerable接口,里面的方法全部是自己實現的了,比如:

findFluent.Skip(10).Limit(10).SortBy(t => t.Age);使用起來順手多了,而且都是到數據庫端執行的.

就連取集合的First方法,也是經過服務端處理的,不信你看:

你再看看Single方法:

查詢的時候都做了Limit處理,…………………………但是會不會突然心頭一緊。怎么Single的時候find.Limit(2)啊,太奇怪了。不過聰明的小伙伴,想一會兒應該知道咋回事了,哈哈!

 

再看看分組查詢優化,我就不說了,把c#里寫js代碼的部分直接搞掉了。使用lamda表達式的方式實現了,如下:

var dataGroup = collection.Aggregate().Group(t => t.Age, g => new { _id = g.Key, TotalAge = g.Sum(x => x.Age) });

需要注意的是2.0都是異步編程,熟悉下用法就行了,這也是.net4.5比較大的改變:把異步編程變得簡單。

 

先寫這么多了,那里說的不對的地方大家多多指出。另外身邊有誰還堅持用1.0的,一定要嘗試着去說服他……額……

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM