MongoDB3.2增刪查改方法簡述(CRUD操作)
阿新 • • 發佈:2018-12-24
一、前序
無論什麼資料庫,都必須會有增刪查改的操作,只是方法形式不一樣而已,其實思路還是差不多的,
下面我們就對MongoDB3.2版本的文件操作簡述並驗證一下
二、查select:
簡單查詢:
根據條件只顯示某一欄位值
三、 插入insert 普通插入
update預設情況下,只更新一條記錄
語法格式:
upsert的使用即在update時,如果查詢不到相應document,則會直接在集合中insert入一條新document記錄
五、刪除 官方提供的刪除document的方法: db.collection.remove() db.collection.deleteOne() ---3.2新功能,刪除符合條件的第一個document db.collection.deleteMany() ---3.2新功能,刪除符合條件的所有文件 對於大量的刪除操作,把你想要保留的文件複製到一個新的集合然後使用 db.collection.drop() 方法刪除原集合或許會更高效(官方建議) 用法最活躍的remove() 語法格式:
實驗結果: 插入一條、更新其中一條、刪除其中一條
排序查詢:>db.t1.find() { "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 } { "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 4, "j" : 2 } { "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 2, "j" : 3 } { "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 } { "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
比較查詢:>db.t1.find().sort({j:-1}) ---"1"表示升序,“-1”表示降序 { "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 } { "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 2, "j" : 3 } { "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 4, "j" : 2 } { "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 } { "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
>db.t1.find({j:{$gt:2,$lte:4}}) ---查詢j欄位大於2,小於等於4的記錄
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 2, "j" : 3 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
$gt:大於
$lt:小於
$gte:大於等於
$lte:小於等於
根據條件只顯示某一欄位值
如需消去_id欄位顯示,可:> db.t1.find({x:1},{j:true}) ---查詢x=1的記錄,且只顯示j欄位值 { "_id" : ObjectId("585ce007d993c80e8713c7bd"), "j" : 1 } { "_id" : ObjectId("585ce007d993c80e8713c7be"), "j" : 2 } { "_id" : ObjectId("585ce007d993c80e8713c7bf"), "j" : 3 }
> db.t1.find({x:1},{j:true,_id:false})
{ "j" : 1 }
{ "j" : 2 }
{ "j" : 3 }
多個值in查詢(類似IN)
> db.t1.find({j:{$in:[1,4]}}) ---j=1或j=4的記錄
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
多個值and查詢(類似AND)
> db.t1.find({x:1,j:{$gt:1}}) ---x=1 and j>1條件記錄
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 1, "j" : 2 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 1, "j" : 3 }
多個值or查詢(類似OR)
> db.t1.find({$or:[{x:4},{j:{$lte:2}}]}) ---x=4 or j<=2的條件記錄
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 1, "j" : 2 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
多個值or and 查詢
> db.t1.find({x:1,$or:[{j:{$lt:2}},{j:3}]}) ---x=1 and (j<2 or j=3)
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 1, "j" : 3 }
查詢表中不包括 j 欄位的記錄
>db.t6.find({j:{$exists:false}}) ---查詢包含j欄位的話,就是$exists:true
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
查詢子文件中存在某個欄位的記錄
可以使用點來連線>db.getCollection('t6').find({"kk.city":{$exists:true}}) ---查詢kk子文件中存在有city欄位的資料
根據子文件中某幾個欄位的值進行匹配查詢: >db.t6.find({kk:{deviceID:222,city:"Tianjin"}}) ---查詢kk子文件中deviceID=222且city:"Tianjin"的記錄
{ "_id" : 1, "x" : 2, "kk" : { "deviceID" : 222, "city" : "Tianjin" } }
或
> db.t6.find({"kk.deviceID":222,"kk.city":"Tianjin"}) ---與上一個方法一樣的效果,注意雙引號的使用
只返回子文件中的某些欄位> db.t6.find({},{"kk.deviceID":1,_id:0})
{ "kk" : { "deviceID" : 222 } }
{ "kk" : { "deviceID" : 222 } }
{ }
{ }
只返回陣列中的第幾個元素值> db.t6.find({x:3},{_id:0,x:0,pp:{$slice:-1}}) ---查詢x=3的記錄,且只返回陣列pp的最後一個元素值,使用$slice
{ "pp" : [ "p3" ] }
三、 插入insert 普通插入
>db.t2.insert({x:5,j:6})
陣列插入
>db.t2.insert([{_id:11,item:"pencil",qty:50,type:"no2"}, ---以陣列的形式插入多個document
... {item:"pen",qty:20},
... {item:"eraer",qty:25}]
... )
單一插入
>db.t2.insertOne({item:"card",qty:15},{a:22,b:33}) ---只會插入第一個document
多文件插入
> db.t2.insertMany([{item:"p",qty:1},{item:"e",qty:2},{item:"n",qty:3}])
四、更新UPDATE
更新其實也有很多種方法:
db.collection.updateOne() ---3.2版本的新功能,只更新匹配查詢條件的第一個document記錄
db.collection.updateMany() ---3.2版本的新功能,更新匹配查詢條件的所有document記錄,其餘功能和update()基本一致
db.collection.update()
db.collection.replaceOne() ---3.2版本的新功能,只更新替換匹配查詢條件的第一個document記錄,並且是替換整個
先單獨試驗一下各自常用功能,後續再詳述上述方法之不同
4.1 update()update預設情況下,只更新一條記錄
語法格式:
db.collection.update(
<query>, ---以{}形式填寫查詢條件,與find()方法一樣
<update>, ---更新動作,常用的是$set,以設定欄位的新值
{
upsert: <boolean>, ---可選,當query的document不存在時,直接insert一個文件
multi: <boolean>, ---update()預設最多隻更新一條記錄,multi:true可以多文件更新
writeConcern: <document> ---一個完成返回模式,詳細可檢視官方文件
})
例項collection:>db.t3.find()
{
_id: 100,
sku: "Johnny",
quantity: 250,
instock: true,
reorder: false,
details: { model: "14Q2", make: "xyz" },
tags: [ "apparel", "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
{
_id: 101,
sku: "Johnny",
quantity: 251,
instock: true,
reorder: false,
details: { model: "22Q2", make: "abc" },
tags: [ "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
使用$set >db.t3.update(
{ _id: 100 },
{ $set:
{
quantity: 500,
details: { model: "14Q3", make: "xyz" },
tags: [ "red", "outerwear", "clothing" ]
}
}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) ---返回值,提示只更新了一條記錄,事實確實也是隻更新了一條
>db.t3.find()
{
_id: 100,
sku: "Johnny",
quantity: 500,
instock: true,
reorder: false,
details: { model: "14Q3", make: "xyz" },
tags: [ "apparel", "clothing","red" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
{
_id: 101,
sku: "Johnny",
quantity: 251,
instock: true,
reorder: false,
details: { model: "22Q2", make: "abc" },
tags: [ "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
--使用$set操作更新了三種類型,quantity數值,details嵌入式文件型,tags陣列型
upsert的使用即在update時,如果查詢不到相應document,則會直接在集合中insert入一條新document記錄
>db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
> db.t1.update({x:5},{$set:{j:5}},{upsert:true}) ---因為查詢不到x:5的記錄,所以直接insert一條document記錄
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5860c6acc2742b7e1500ca53")
})
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("5860c6acc2742b7e1500ca53"), "x" : 5, "j" : 5 }
更新整個document(注意是document,不是整個collection)> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
> db.t1.update({x:3},{x:3,j:6})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" :1 })
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3, "j" : 6 } ---直接更新了此document的內容
注:因在update這一部分沒有加諸如$set之類的操作,僅以field:value的形式,則會直接更新整個document,這樣可以用來新增或刪除欄位
新增新欄位 > db.t1.update(
... {x:5},
... {$set:{y:5}},
... {multi:true} ---此引數可更新多個document,可選項
... )
> db.t1.find()
{ "_id" : ObjectId("5860c6acc2742b7e1500ca53"), "x" : 5, "j" : 5, "y" : 5 } ---之前document中沒有“y”欄位,
重新命名欄位名($rename)>db.t2.update(
{_id:"12_1_001"},
{$rename:{"class_id":"clasID"}} ---class_id是舊欄位名,classID是新名字
)
刪除某個欄位
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 6, "j" : 6, "y" : 6}
> db.t1.update({x:6},{$unset:{y:5}}) ---y欄位之後的值不重要,不寫6,依然可以刪除此欄位
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 6, "j" : 6 }
db.collection.replaceOne()
是直接替換符合條件的整個document
語法格式:
db.collection.replaceOne(
<filter>, ---查詢條件
<replacement>, ---待替換後的新document內容
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>
})
例項:
> db.t1.find()
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 6, "j" : 6 }
> db.t1.replaceOne({x:6},{j:7})
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "j" : 7 } ---注意此處少了x:6,因為是直接更新替換了整個document
五、刪除 官方提供的刪除document的方法: db.collection.remove() db.collection.deleteOne() ---3.2新功能,刪除符合條件的第一個document db.collection.deleteMany() ---3.2新功能,刪除符合條件的所有文件 對於大量的刪除操作,把你想要保留的文件複製到一個新的集合然後使用 db.collection.drop() 方法刪除原集合或許會更高效(官方建議) 用法最活躍的remove() 語法格式:
db.collection.remove(
<query>,
{
justOne: <boolean>, ---true或false 表示只刪除符合查詢條件順序的第一個document
writeConcern: <document>,
collation: <document>
})
注:刪除集合的文件,不會刪除索引(即使刪除所有文件)> db.t4.insert({a:1,b:2})
>db.t4.createIndex({a:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>db.t4.remove({}) ---傳入空文件{},則表示刪除集合中的所有文件
> db.t4.getIndexes() ---此時查詢索引,依然存在
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "tt.t4"
},
{
"v" : 1,
"key" : {
"a" : 1
},
"name" : "a_1",
"ns" : "tt.t4"
}
]
只刪除符合條件的第一條document記錄
> db.t4.find()
{ "_id" : ObjectId("5860dd2b22c84900e7e4c02c"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("5860dd2d22c84900e7e4c02d"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("5860dd3022c84900e7e4c02e"), "a" : 1, "b" : 3 }
> db.t4.deleteOne({a:1})
> db.t4.find()
{ "_id" : ObjectId("5860dd2d22c84900e7e4c02d"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("5860dd3022c84900e7e4c02e"), "a" : 1, "b" : 3 }
或使用remove()
>db.t4.remove({a:1},true) ---兩種寫法,也可以這樣寫:db.t4.remove({a:1},{justOne:true})
> db.t4.find()
{ "_id" : ObjectId("5860dd2d22c84900e7e4c02d"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("5860dd3022c84900e7e4c02e"), "a" : 1, "b" : 3 }
六、批量操作
上面講了一堆增刪改查的操作,不過都是單一英雄操作,如果我們想批量操作怎麼辦,那就拍一個《復仇者聯盟》就好了呀----BulkWrite()
官方的介紹是:MongoDB提供給客戶端可以批量執行寫操作的能力,不過只能影響一個collection
BulkWrite()支援一下寫操作:
語法格式:
>db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
})
operation1、operation2都是一個個的修改操作,以文件的形式放在 [ ] 陣列中
ordered:預設是true,即按照修改操作的順序執行,如果過程中某一操作報錯,則剩餘的操作將中斷
false時,則是平行執行,一個操作的報錯異常,不會影響到其餘操作,但官方一般不建議,因為沒有保證性
實驗:
> db.t4.find()
> db.t4.bulkWrite([
... {insertOne:{"document":{_id:1,a:1,name:"James"}}},
... {insertOne:{"document":{_id:2,a:2,name:"Johnny"}}},
... {updateOne:{"filter":{a:1},"update":{$set:{name:"Jack"}}}},
... {deleteOne:{"filter":{a:2}}}])
{
"acknowledged" : true,
"deletedCount" : 1,
"insertedCount" : 2,
"matchedCount" : 1,
"upsertedCount" : 0,
"insertedIds" : {
"0" : 1,
"1" : 2
},
"upsertedIds" : {
}
}
> db.t4.find()
{ "_id" : 1, "a" : 1, "name" : "Jack" }
實驗結果: 插入一條、更新其中一條、刪除其中一條