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

前言

  最近閒的時間有點多,因此仍是寫博客吧。數據庫

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

  Mongo C#驅動1.0到2.0設計方面的差異很是大。c#

正文

先說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方法與數據庫中執行構建查詢的方法混在一塊兒,這點是能夠改進的。不然可能出現一下問題:this

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

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

 

 

這樣看起來沒問題,可是在使用時,以下代碼:翻譯

這是段經常使用的分頁代碼,我天真的覺得他會將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的,必定要嘗試着去說服他……額……

相關文章
相關標籤/搜索