1. 程式人生 > >MongoDB3.2增刪查改方法簡述(CRUD操作)

MongoDB3.2增刪查改方法簡述(CRUD操作)

一、前序 無論什麼資料庫,都必須會有增刪查改的操作,只是方法形式不一樣而已,其實思路還是差不多的, 下面我們就對MongoDB3.2版本的文件操作簡述並驗證一下 二、查select: 簡單查詢:
>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:小於等於
根據條件只顯示某一欄位值
> 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 }
如需消去_id欄位顯示,可:
> 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" }


實驗結果:      插入一條、更新其中一條、刪除其中一條