Mongodb Manual閱讀筆記:CH2 Mongodb CRUD 操做

2 Mongodb CRUD 操做

Mongodb Manual閱讀筆記:CH2 Mongodb CRUD 操做
Mongodb Manual閱讀筆記:CH3 數據模型(Data Models)
Mongodb Manual閱讀筆記:CH4 管理
Mongodb Manual閱讀筆記:CH5 安全性
Mongodb Manual閱讀筆記:CH6 聚合
Mongodb Manual閱讀筆記:CH7 索引
Mongodb Manual閱讀筆記:CH8 複製集
Mongodb Manual閱讀筆記:CH9 Sharding
html

 

 

mongodb提供了建立,讀取,修改,刪除簡稱CRUDsql

2 Mongodb CRUD 操做... 1mongodb

2.1 Mongodb CRUD簡介... 2shell

2.1.1數據庫操做... 3數據庫

2.1.1.1查詢... 3json

2.1.1.2數據修改... 3數組

2.1.2 相關特性... 3安全

2.1.2.1索引... 3網絡

2.1.2.2讀偏好... 3併發

2.1.2.3寫注意(write concern... 3

2.2 Mongodb CRUD概述... 3

2.2.1讀操做... 3

2.2.1.1遊標... 4

2.2.1.2優化查詢... 5

2.2.1.3查詢計劃... 5

2.2.1.4分佈式查詢... 5

2.2.2寫操做... 5

2.2.2.1寫注意(write concern)7

2.2.2.2分佈式寫... 7

2.2.2.3寫操做性能... 7

2.2.2.4存儲性能... 7

2.2.2.5大數據量寫入... 8

2.2.2.6行留白(Record Padding... 8

2.3 Mongodb CRUD教程... 8

2.3.1 插入文檔... 8

2.3.1.1使用insert插入文檔... 8

2.3.1.2使用update插入文檔... 8

2.3.1.3使用save插入文檔... 9

2.3.2查詢文檔... 9

2.3.2.1 查詢所有的文檔... 9

2.3.2.2指定條件查詢文檔... 9

2.3.2.3使用and條件查詢... 9

2.3.2.4 使用or條件查詢... 9

2.3.2.5使用andor 查詢... 10

2.3.2.6子文檔... 10

2.3.2.7數組... 10

2.3.3限制查詢返回的字段... 11

2.3.3.1 返回全部字段... 11

2.3.3.2返貨指定字段和_id. 11

2.3.3.3只返回指定字段... 11

2.3.3.4 返回除某字段外的全部字段... 12

2.3.3.5數組字段的Projection. 12

2.3.4mongo shell中迭代一個遊標... 12

2.3.4.1手動迭代遊標... 12

2.3.4.2迭代索引... 12

2.3.5分析查詢性能... 12

2.3.5.1 評估查詢性能... 13

2.3.5.2比較索引性能... 13

2.3.6修改文檔... 13

2.3.6.1使用update修改多個文檔... 13

2.3.6.2使用save修改文檔... 14

2.3.7刪除文檔... 14

2.3.7.1刪除全部文檔... 14

2.3.7.2 帶條件刪除文檔... 14

2.3.7.3 帶條件刪除一個文檔... 14

2.3.8 執行二階段提交... 14

2.3.8.1背景... 14

2.3.8.2模式... 15

2.3.8.3在生產環境使用二階段提交... 16

2.3.9 建立tailable cursor. 16

2.3.9.1概述... 16

2.3.9.2 C++例子... 17

2.3.10隔離操做順序... 17

2.3.11建立自增字段... 17

2.3.11.1計數Collection. 17

2.3.11.2 樂觀循環... 18

2.3.12 更新數組中限制更新行數... 18

2.3.12.1 方式... 18

2.4 MongoDB CRUD 指南... 19

2.4.1 查詢遊標方法... 19

2.4.2 查詢和數據操做... 19

2.4.3 MongoDB CRUD指南文檔... 19

2.4.3.1 寫注意(write concern)19

2.4.3.2 sql mongodb的對照表... 20

2.4.3.3 mongodb驅動和客戶端lib. 20

 

2.1 Mongodb CRUD簡介

mongodb存儲的文檔是和json格式相似的,可是mongodb存儲的是BSON也就是,以2進制方式保存JSON格式數據。在mongodb中文檔至關於記錄,而存文檔的Collection至關於表。

2.1.1數據庫操做

2.1.1.1查詢

Mongodb能夠對一個collection經過條件來過濾文檔,而且能夠用projection選擇輸出

2.1.1.2數據修改

建立,更新,刪除數據,只能修改單個collection(不包含嵌入方式)

2.1.2 相關特性

2.1.2.1索引

Mongodb能夠順序的表示,也能夠強制惟一性保存,mongodb中索引也是用b樹保存,

2.1.2.2讀偏好

讀偏好主要是用在複製集羣中,從哪一個實例中讀取。

2.1.2.3寫注意(write concern

不一樣的寫注意保證了不一樣的數據寫入要求,級別越低寫入越快,可是寫入安全性越低

2.2 Mongodb CRUD概述

讀操做:遊標,查詢優化,分佈式查詢

寫操做:寫注意,分佈式寫操做

2.2.1讀操做

查詢接口

         Mongodb經過提供的接口db.collection.find()方法來查詢數據,會返回一個遊標

查詢行爲

         1.全部的查詢只能針對一個collection

         2.能夠經過limitsskipssort來影響查詢結果

         3.sort()來範圍查詢的順序

         4.update修改數據和select的條件語法同樣

         5.aggregation(聚合)管道中,$match管道提供了對mongodb的訪問

查詢語句

Projection

         Projection用來限制輸出那些字段,_id是默認輸出的。

         Projection行爲

                   1._id會默認出現,除非顯示設置

                   2.對於包含array的字段,提供了$elemMatch,$slice,$等操做符

                   3.對於聚合,使用$Project來處理

2.2.1.1遊標

         mongodb查詢db.collection.find()返回一個遊標,若沒有分配給一個變量直接運行20

         遊標行爲對於遊標默認不活動時間超過10分鐘就會被銷燬,固然能夠指定noTimeout標記,來先限制等待。

         遊標隔離級別遊標在有效期內是不隔離的,如有寫入操做就會影響,可使用快照模式來處理

         遊標Batch數據從mongodb到客戶端是以batch的方式,batch的大小最大不超過最大BSON文檔的大小,對於不少查詢而言,第一個batch返回101個文檔,或者1MB的大小,以後是4MB

         對於包含sort的查詢可是沒有索引,mongodb會導入到內存而後排序,會在第一個batch的時候返回全部的結果。用cursor.hasnext()cursor.next()的組合來看有沒有下一個batct,獲取下一個batch

         遊標信息經過命令cursorInfo來獲取遊標的信息:1.打開的遊標總數,2.當前使用的客戶端遊標大小,3.從服務重啓來,超時的遊標數。

2.2.1.2優化查詢

         索引和其餘數據庫中的同樣,減小了不必數據的查詢。

         建立索引來支持查詢使用db.collection.ensureIndex()來建立索引

         索引的選擇度某些查詢操做時選擇度不好,好比$nin,$ne,高選擇度的才能夠更好的使用索引,$regex      也是沒有辦法使用索引的。

         覆蓋查詢覆蓋查詢的條件:1.全部的字段都是索引的一部分,2.全部返回的字段也在索引中

2.2.1.3查詢計劃

Mongodb優化器處理查詢,並根據索引選擇一個最有效的索引,當collection的數據量被改變優化器會偶爾重建計劃,可使用explain()來查看執行計劃。

         查詢優化

優化器建立計劃的過程:1.經過不一樣的索引,併發的執行查詢,2.記錄負荷的結果到buffer中,3.當非排序的查詢計劃所有返回,或者順序的執行計劃所有返回,或者順序的執行計劃返回了超過了一個指標,那麼會中止其餘執行的計劃並選擇這個計劃

         計劃重建

當發生如下事件,計劃會被重建:1.超過1000個寫入,2.重建索引,3.添加或者刪除索引,4.服務進程重啓

2.2.1.4分佈式查詢

         Sharded集羣中讀Sharded容許數據分區,並對應用程序透明,查詢會經過路由到達相關的實例中,經過shard key若沒有shard key,查詢會分發到索引的shard實例中取執行。

         從複製集羣中讀,在複製集羣中使用讀偏好,來決定從哪一個實例中讀取數據,讀偏好設置有一下幾個好處:1.減小延遲,2.提供讀的帶寬,3.備份做用,4.容災切換。同時也要注意,主庫和分庫之間的延遲,分庫不能表明當前主庫的數據狀態。

2.2.2寫操做

和讀同樣寫操做只能用在一個collection上。

建立

         經過接口,db.collection.insert()collection上建立一個文檔,若update接口在有upset的標記下,也能夠實現建立文檔的功能。

插入的行爲

         若是你插入時,沒有指定_id那麼mongodb會分配一個,若指定了_id須要保持在collection中是惟一的。

更新

         經過接口,db.collection.update()來實現更新操做,也能夠用save

  

更新行爲

         update默認只對一行進行更新,若要對多行進行更新要使用multi選項,通沒有指定相似set的參數,就會把全部影響的文檔替換,當更新是,文檔的大小超過了原先分配的大小,那麼會從新分配空間,而後把文檔放入,這樣會致使,文檔內的字段重排。

刪除

         刪除經過接口,db.collection.delete()實現。

刪除的行爲

         默認使用delete不太條件,會把因此的文檔所有刪除

寫操做的隔離性

         修改一個文檔,能夠支持原子性,可是對多個文檔的修改就不支持原子性,儘管如此單仍是可使用隔離操做(isolaation_operator)。也能夠經過人工方式實現2階段提交,來保證隔離性。

2.2.2.1寫注意(write concern)

         弱寫注意,可能會致使一些錯誤,由於不須要等服務端返回寫入成功,強寫注意,client能夠等待寫入完成。db.runCommand( { getLastError: 1, w: 2 } )來配置。

 

         寫注意級別:忽略錯誤(Error Ingored),最低級的級別,mongodb不會通知寫入操做完成,包含        發生錯誤,性能最佳,可是會影響寫入數據的一致性和持久性,w:-1

         不通知mongodb不會通知寫入成功或者失敗,可是當發生錯誤是,仍是會盡力接受和處理錯誤,能夠發現由系統網絡配置致使的網絡錯誤。w:0

         通知:能夠取回一個寫入操做信息,這個級別,容許客戶端抓取網絡,重複key等錯誤,w:1mongodb默認使用這個級別,寫注意默認使用無參數的getLastError,對於複製集羣能夠在getLastErrorDefaults中定義默認的寫注意,若沒有定義默認使用getLastError取通知.

         日誌:使用這個級別,只有在提交,寫入日誌後,服務纔會通知寫入操做,這樣能夠保證服務崩潰後數據庫的恢復。使用這個操做要指定w:1,j:true

         複製通知:使用這個級別能夠保證,寫操做寫入到了複製集羣,w:>1,在複製集羣下,只要再設置j:true,主庫就能夠用日誌寫注意級別。

2.2.2.2分佈式寫

         sharded集羣中寫:能夠根據shard key來對分區插入數據,能夠提升寫入性能,若沒有key,會被廣播到全部的shard,若數據庫只插入到一個key,那麼可能照成單點性能問題。

         在複製集中寫:在複製集中寫入,會被寫入到primary上,而後記錄在oplog或者log中,而後根據oplog分發到分庫中,對於密集的寫入操做會致使分庫和主庫之間嚴重的延遲,雖然能夠經過寫注意保證一致性,可是會形成寫入性能問題

2.2.2.3寫操做性能

         索引:和其餘數據庫同樣,寫操做會修改索引,會帶來一些性能消耗。

         文檔增加update 操做文檔的空間時,會分配一個新空間,而後把文檔複製進去,這樣會加大update的時間,in-place比文檔增加來的有效。

2.2.2.4存儲性能

         硬件:不少元素和存儲系統有關,影響着服務的性能,如,隨機讀寫性能,磁盤cache,預讀,RAID級別。

         日誌mongodb使用順序寫方式來記錄日誌,日誌提供了一致性和crash彈性,考慮一下方面來增長日誌性能:1.使用獨立的設備,2.若寫注意級別爲日誌,mongodb經過減小提交間隔來減小寫負荷,3.經過手動配置journalCommitInterval來減小提交間隔。

2.2.2.5大數據量寫入

         使用insert方法insert方法經過傳入一個數組來執行大數據量寫入。經過寫注意的設置大數據量寫入,能夠顯著的提升性能。而且經過ContinueOnError選項可讓批量插入有錯誤下還能完成。

         Shard集羣中ContinueOnError只在非分片中有效,這類大批量寫入,對sharded集羣來講會下降性能若要寫入考慮一下方案:

                  預分配splits:大批量導入中,若collection是空的,那麼只有一個spilt,當插入時    從新分配split致使性能問題因此要預先split

                   避免單調增加:可能大批量插入只針對一個sharded key,這樣sharded的性能就沒        有辦法體現,如沒法避免,能夠考慮:1.二進制方式翻轉shard key2.key的前16位和  16位互換。

2.2.2.6行留白(Record Padding

         由於超出文檔就會從新分配,爲了不這個問題,能夠事先留白,減小重分配的可能性。

         留白因子:可使用db.collection.stats()查看當前的paddingFactor,留白的大小能夠經過一個公式計算:padding size = (paddingfactor-1)*<document size>。留白並不能對每一個文檔作準確的設置,只能根據文檔大小的平均數。留白的大小隻能經過執行compact或者repairDatabase選項回收。

         刪除留白:能夠經過compactrepairDatabase和初始化複製同步選項來移除,導出導入也能夠。

         行分配策略:爲了更加有效的使用由於刪除而空閒的空間,或者文檔從新分配的空間,能夠指定mongodb分配的行大小,大小爲2n次。

2.3 Mongodb CRUD教程

2.3.1 插入文檔

mongodb中,可使用insertupdatesave來插入數據

2.3.1.1使用insert插入文檔

inventory插入數據:db.inventory.insert( { _id: 10, type: "misc", item: "card", qty: 15 } )

2.3.1.2使用update插入文檔

使用update插入文檔的時候要指明upserttrue,表示若是有數據則修改,沒數據則插入

db.inventory.update(

{ type: "book", item : "journal" },

{ $set : { qty: 10 } },

{ upsert : true }

)

{ "_id" : ObjectId("51e8636953dbe31d5f34a38a"), "item" : "journal", "qty" : 10, "type" : "book" }

插入的文檔若是沒有指定_id mongodb會自動分配一個_id

2.3.1.3使用save插入文檔

inventory插入數據db.inventory.save( { type: "book", item: "notebook", qty: 40 } )

{ "_id" : ObjectId("51e866e48737f72b32ae4fbc"), "type" : "book", "item" : "notebook", "qty" : 40 }

2.3.2查詢文檔

mongodb中,find()返回一個遊標,經過遊標來獲取返回的文檔。

2.3.2.1 查詢所有的文檔

可使用以下來查詢全部的文檔:

db.inventory.find( {} )db.inventory.find()

2.3.2.2指定條件查詢文檔

若是要在inventory中查詢typefood或者snacks的:

db.inventory.find( { type: { $in: [ 'food', 'snacks' ] } } )

2.3.2.3使用and條件查詢

mongodb中,只要都好分開就表示and條件

db.inventory.find( { type: 'food', price: { $lt: 9.95 } } )

2.3.2.4 使用or條件查詢

db.inventory.find(

{ $or: [

{ qty: { $gt: 100 } },

{ price: { $lt: 9.95 } }

]

}

)

2.3.2.5使用andor 查詢

db.inventory.find( { type: 'food', $or: [ { qty: { $gt: 100 } },

{ price: { $lt: 9.95 } } ]

} )

2.3.2.6子文檔

當要查詢子文檔的時候,能夠指定子文檔的全部值,也可使用.(點號) 獲取子文檔的字段值。

精確的匹配文檔

也就是匹配整個子文檔

db.inventory.find(

{

producer: {

company: 'ABC123',

address: '123 Street'

}

}

)

使用子文檔的字段匹配

用點號獲取子文檔的值

db.inventory.find( { 'producer.company': 'ABC123' } )

2.3.2.7數組

匹配方式和子文檔相似

匹配整個數組

db.inventory.find( { tags: [ 'fruit', 'food', 'citrus' ] } )

匹配某個元素

只要某個元素在數組中都會被匹配

db.inventory.find( { tags: 'fruit' } )

匹配指定元素

db.inventory.find( { 'tags.0' : 'fruit' } )

子文檔數組

使用數組全部匹配子文檔中的字段:db.inventory.find( { 'memos.0.by': 'shipping' } )

多字段匹配

db.inventory.find(

{

'memos.memo': 'on time',

'memos.by': 'shipping'

}

)

2.3.3限制查詢返回的字段

Projection能夠限制字段的輸出

2.3.3.1 返回全部字段

Find,函數第二個參數就是projection若是不填就是所有返回

2.3.3.2返貨指定字段和_id

db.inventory.find( { type: 'food' }, { item: 1, qty: 1 } )

其中_id字段是默認返回的全部不用指定

2.3.3.3只返回指定字段

db.inventory.find( { type: 'food' }, { item: 1, qty: 1, _id:0 } )

由於_id是默認返回的,因此要設置_id不返回。

2.3.3.4 返回除某字段外的全部字段

db.inventory.find( { type: 'food' }, { type:0 } )

2.3.3.5數組字段的Projection

對於數組來講惟一可用的projection操做就是$elemMath$slice

2.3.4mongo shell中迭代一個遊標

find函數沒有賦值給變量,在shell中會直接迭代20次。

2.3.4.1手動迭代遊標

經過如下方式能夠直接迭代20

var myCursor = db.inventory.find( { type: 'food' } );

myCursor

也能夠手動迭代

var myCursor = db.inventory.find( { type: 'food' } );

var myDocument = myCursor.hasNext() ? myCursor.next() : null;

if (myDocument) {

var myItem = myDocument.item;

print(tojson(myItem));

}

還能夠用forEach方法

var myCursor = db.inventory.find( { type: 'food' } );

myCursor.forEach(printjson);

2.3.4.2迭代索引

mongo shell中能夠能夠直接把遊標toArray(),而後直接訪問數組便可。

var myCursor = db.inventory.find( { type: 'food' } );

var documentArray = myCursor.toArray();

var myDocument = documentArray[3];

2.3.5分析查詢性能

Explain()遊標方法,這個方法用來分析查詢的效率,肯定如何使用索引。

2.3.5.1 評估查詢性能

db.inventory.find( { type: 'food' } ).explain()

結果

{

"cursor" : "BtreeCursor type_1",

"isMultiKey" : false,

"n" : 5,

"nscannedObjects" : 5,

"nscanned" : 5,

"nscannedObjectsAllPlans" : 5,

"nscannedAllPlans" : 5,

"scanAndOrder" : false,

"indexOnly" : false,

"nYields" : 0,

"nChunkSkips" : 0,

"millis" : 0,

"indexBounds" : { "type" : [

[ "food",

"food" ]

] },

"server" : "mongodbo0.example.net:27017"

}

Cursor的值爲btreecursor表示是用了索引

n表示返回的文檔數

2.3.5.2比較索引性能

若是要比較索引之間的性能可使用hint來強制

db.inventory.find( { type: 'food' } ).hint( { type: 1 } ).explain()

db.inventory.find( { type: 'food' } ).hint( { type: 1, name: 1 } ).explain()

2.3.6修改文檔

修改文檔的操做有,update saveupdate是修改文檔,save若是文檔存在則替換文檔。

2.3.6.1使用update修改多個文檔

要修改多個文檔時,要把multi-true設置上。

db.inventory.update(

{ type : "book" },

{ $inc : { qty : -1 } },

{ multi: true }

)

2.3.6.2使用save修改文檔

Save能夠替換已經存在的文檔

db.inventory.save(

{

_id: 10,

type: "misc",

item: "placard"

}

)

2.3.7刪除文檔

刪除文檔通常使用remove方法

2.3.7.1刪除全部文檔

直接寫不帶參數的remove就會把collection中的文檔所有刪除。

db.inventory.remove()

2.3.7.2 帶條件刪除文檔

db.inventory.remove( { type : "food" } )

2.3.7.3 帶條件刪除一個文檔

db.inventory.remove( { type : "food" }, 1 )

2.3.8 執行二階段提交

當處理多文檔的更新和事務,可使用二階段提交的方式來寫多個文檔

2.3.8.1背景

單文檔操做是原子的,多文檔沒有,因此多文檔的操做不能有原子性保障,當執行事務時就可能發生如下問題:

1.原子性:若是一個操做失敗,事務必須回滾到以前的狀態

2.隔離性:同步發生的事務,在事務過程當中必須看到一致性的數據

3.一致性:若是發生數據庫錯誤,中斷了事務,數據庫必須可以恢復到一致的狀態

多文檔的寫可使用二階段提交

2.3.8.2模式

概述

假設要作轉帳操做,咱們有一個accounts collection和一個transactions collection用來保存用戶數據和事務數據。

db.accounts.save({name: "A", balance: 1000, pendingTransactions: []})

db.accounts.save({name: "B", balance: 1000, pendingTransactions: []})

事務描述

設置事務初始化狀態:在建立的 transactions中插入一條數據而且狀態爲initial

db.transactions.save({source: "A", destination: "B", value: 100, state: "initial"})

而後把事務狀態設置爲pending:在要處理事務以前把事務狀態設置爲pending表示處理這個事務。db.transactions.update({_id: t._id}, {$set: {state: "pending"}})

應用事務到2個帳號上

db.accounts.update({name: t.source, pendingTransactions: {$ne: t._id}}, {$inc: {balance: -t.value}, $push: {pendingTransactions: t._id}})

db.accounts.update({name: t.destination, pendingTransactions: {$ne: t._id}}, {$inc: {balance: t.value}, $push: {pendingTransactions: t._id}})

更新accountpendingTransaction中沒有t._id的事務,就是t._id不是已經在處理事務,而後設置值,並把設置上pendingTransaction

設置事務提交狀態db.transactions.update({_id: t._id}, {$set: {state: "committed"}})

刪除pending事務

db.accounts.update({name: t.source}, {$pull: {pendingTransactions: t._id}})

db.accounts.update({name: t.destination}, {$pull: {pendingTransactions: t._id}})

設置事務完成

db.transactions.update({_id: t._id}, {$set: {state: "done"}})

從錯誤場景中恢復

可能會出現錯誤的場景:

1.在初始化事務,應用事務到2個帳號上之間出錯,爲了恢復應用程序應該獲取pending狀態的事務,而後繼續處理。

2.發生在應用事務,事務完成之間的錯誤,爲了恢復應用程序應該獲取done狀態的事務,而後繼續處理。

回滾:某些場景就須要回滾操做

1.當應用事務以後,已經提交了事務,就不該該去回滾事務,而是從新建立一個新的事務,來交換數據

2.在建立事務後,可是沒有應用事務,可使用一下步驟:

設置事務狀態爲取消db.transactions.update({_id: t._id}, {$set: {state: "canceling"}})

Undo事務

db.accounts.update({name: t.source, pendingTransactions: t._id}, {$inc: {balance: t.value}, $pull: {pendingTransactions: t._id}})

db.accounts.update({name: t.destination, pendingTransactions: t._id}, {$inc: {balance: -t.value}, $pull: {pendingTransactions: t._id}})

把事務狀態修改成已取消db.transactions.update({_id: t._id}, {$set: {state: "canceled"}})

多應用程序:多應用程序的時候很容易形成一致性問題和衝突。在這種狀況下,在transaction中加入application字段,來區別應用程序。而且使用findAndModify()

t = db.transactions.findAndModify({query: {state: "initial", application: {$exists: 0}},

update: {$set: {state: "pending", application: "A1"}},

new: true})

2.3.8.3在生產環境使用二階段提交

在例子中,咱們假設了一些東西好比:

1.老是能夠回滾一個用戶

2.帳號的剩餘能夠爲負數

可是在生產環境下須要考慮:

1.在把事務設置爲pending的時候,須要查看帳號是否有足夠的資金。

2.當事務設置提交時,須要修改借貸方

固然這些操做時在一個文檔裏面的,是原子的

也須要考慮:

1.數據庫接口的寫注意(wirte concern)

2.mongodjournaling是否開啓確保數據庫非乾淨關閉後數據庫狀態的恢復。

2.3.9 建立tailable cursor

2.3.9.1概述

默認遊標使用完以後就會被關閉,可是Tailable Cursor不會,當文檔有插入,Tailable Cursor也能夠取到。對於高寫入的capped collection上使用tailable cursor太昂貴。

Tailable cursor有一下特色:

1.遊標不會使用索引,以天然順序返回

2.tailable cursor在初始化階段比較昂貴,新增的文檔代價並非很大。

3.某些狀況下tailable curos會不可用,沒有返回的文檔,返回了collection的末尾,而後被應用程序刪掉了。

2.3.9.2 C++例子

看手冊p75

2.3.10隔離操做順序

看手冊p76

2.3.11建立自增字段

本節介紹2個建立自增的方法,計數collection,樂觀循環(optimistic loop

2.3.11.1計數Collection

使用一個獨立的計數Collection來跟蹤最新的順序,_id表示順序的名,seq表示最新的順序。

1.插入一個userid的初始化值到計數collection

db.counters.insert(

{

_id: "userid",

seq: 0

}

)

2.建立一個getNextSequence函數來獲取一個名字的下一個順序值。

function getNextSequence(name) {

var ret = db.counters.findAndModify(

{

query: { _id: name },

update: { $inc: { seq: 1 } },

new: true

}

);

return ret.seq;

}

3.在插入時使用getNextSequence函數

db.users.insert(

{

_id: getNextSequence("userid"),

name: "Sarah C."

}

)

2.3.11.2 樂觀循環

讀者以爲很奇葩的方法,手冊 p80

2.3.12 更新數組中限制更新行數

2.3.12.1 方式

students collection有一個文檔

{

_id: 1,

scores: [

{ attempt: 1, score: 10 },

{ attempt: 2 , score:8 }

]

}

而後再$push裏面使用$each$sort來實現

db.students.update(

{ _id: 1 },

{ $push: { scores: { $each : [

{ attempt: 3, score: 7 },

{ attempt: 4, score: 4 }

],

$sort: { score: 1 },

$slice: -3

}

}

}

)

輸出結果

{

"_id" : 1,

"scores" : [

{ "attempt" : 3, "score" : 7 },

{ "attempt" : 2, "score" : 8 },

{ "attempt" : 1, "score" : 10 }

]

}

2.4 MongoDB CRUD 指南

2.4.1 查詢遊標方法

Cursor.count:返回文檔的個數

Cursor.explain:顯示查詢的執行計劃

Cursor.hint:強制mongo使用指定的索引

Cursor.limit:顯示遊標返回文檔個數

Cursor.next:獲取遊標中下一個文檔

Cursor.skip:跳過給定數量的文檔

Cursor.sort:對指定字段排序

Cursor.toArray:遊標返回成數組

2.4.2 查詢和數據操做

Db.collection.count:返回collection文檔個數

Db.collection.distinct:以數組方式返回指定字段的不一樣值

Db.collection.find:在collection執行find返回遊標

Db.collection.findOne:返回一個文檔

Db.collection.insert:在collection上建立文檔

Db.collection.remove:刪除collection上的文檔

Db.collection.save:能夠insert,也能夠替換已經存在的文檔

Db.collection.update:修改已經存在的文檔

2.4.3 MongoDB CRUD指南文檔

主要介紹,寫注意(write concern),sql mongodb的對照表,mongodb的驅動和客戶端lib

2.4.3.1 寫注意(write concern)

概述

Write concernmongodb爲寫入提供的保障,可是是經過消耗性能來保證write的安全性。能夠對數據的重要性不一樣分級。

能夠用的write concern

提供write concern,寫入操做以後,驅動使用getLastError來獲取最後才作的信息。返回一個err字段,:

1.null表示寫入成功

2.null就表示具體的錯誤

GetLastErroe的參數:

J或者journal選項:指定這個選項後,mongodb會寫入日誌到磁盤的journal上確保mongodb忽然關閉以後數據不會丟失。

以下:db.runCommand( { getLastError: 1, j: "true" } )

若是在mongod中並無啓用journal,而後getLastError指定了 j:true會返回一個jnote字段包含了這個文檔。

W選項:這個選項能夠停用write concern,也能夠指定複製集的write concern。可選值:

-1:關閉write operation通知

0:關閉基本的寫入操做通知,可是返回socket異常和網絡異常

1:提供通知,說明已經寫入到了單個實例,或者複製集的primary

>1:說明要寫入到>1個實例中。通常用戶複製集,若是這個值大於複製集成員,mongodb會一致等下去。

Majority:確認寫入操做已經傳播到大多數的已配置複製集

Tag設置:使用tag設置能夠很好的控制複製集成員很好的控制的不一樣write concern

getLastError還提供了一個超時,若是給0會一直等待。

2.4.3.2 sql mongodb的對照表

手冊p85

2.4.3.3 mongodb驅動和客戶端lib

手冊p95

相關文章
相關標籤/搜索