MongoDB 沒(méi)有提供類似 SQL 數(shù)據(jù)庫(kù)所具有的自動(dòng)增長(zhǎng)功能(auto-increment)。默認(rèn)情況下,MongoDB 將 _id 字段(使用 12 字節(jié)的 ObjectId)來(lái)作為文檔的唯一標(biāo)識(shí)。但在有些情況下,我們希望 _id 字段值能夠自動(dòng)增長(zhǎng),而不是固守在 ObjectId 值上。
由于這不是 MongoDB 的默認(rèn)功能,所以我們按照 MongoDB 文檔所建議的方式,使用 counters 集合來(lái)程序化地實(shí)現(xiàn)該功能。
counters 集合假設(shè)存在下列文檔 products,我們希望 _id 字段值是一個(gè)能夠自動(dòng)增長(zhǎng)的整數(shù)序列(1、2、3、4 …… n)。
{
"_id":1,
"product_name": "Apple iPhone",
"category": "mobiles"
}
創(chuàng)建一個(gè) counters 集合,其中包含了所有序列字段最后的序列值。
>db.createCollection("counters")
現(xiàn)在,將下列文檔(productid 是它的鍵)插入到 counters 集合中:
{
"_id":"productid",
"sequence_value": 0
}
sequence_value 字段保存了序列的最后值。
使用下列命令將序列文檔插入到 counters 集合中。
>db.counters.insert({_id:"productid",sequence_value:0})
接著,我們創(chuàng)建一個(gè) getNextSequenceValue 函數(shù),該函數(shù)以序列名為輸入,按照 1 的幅度增加序列數(shù),返回更新的序列數(shù)。在該例中,序列名稱為 productid。
>function getNextSequenceValue(sequenceName){
var sequenceDocument = db.counters.findAndModify(
{
query:{_id: sequenceName },
update: {$inc:{sequence_value:1}},
new:true
});
return sequenceDocument.sequence_value;
}
下面,在創(chuàng)建新文檔以及將返回的序列值賦予文檔的 _id 字段過(guò)程中,我們使用 getNextSequenceValue 函數(shù)。
使用下列代碼插入兩個(gè)范例文檔:
>db.products.insert({
"_id":getNextSequenceValue("productid"),
"product_name":"Apple iPhone",
"category":"mobiles"})
>db.products.insert({
"_id":getNextSequenceValue("productid"),
"product_name":"Samsung S3",
"category":"mobiles"})
如上所示,使用 getNextSequenceValue 函數(shù)為 _id 字段設(shè)定值。
為了驗(yàn)證該功能,使用 find 命令來(lái)獲取文檔:
>db.prodcuts.find()
在上面的查詢返回的結(jié)果文檔中,_id 字段值果然是自動(dòng)增長(zhǎng)的:
{ "_id" : 1, "product_name" : "Apple iPhone", "category" : "mobiles"}
{ "_id" : 2, "product_name" : "Samsung S3", "category" : "mobiles" }