2021 iThome 鐵人賽 - DAY6 MongoDB 資料新增(Insert) 與刪除(Delete)

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY6 MongoDB 資料新增(Insert) 與刪除(Delete)

連線

連線方法如同前面文章提到的,這邊就不再贅述了。

首先我們直接進入一個全新的資料庫資料庫 films

1
2
3
4
5
6
7
> use films
switched to db films
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>

這邊可以看到雖然我們 use films,但只要還沒有寫入資料前,database 還不會真正建立出來,現階段不需要擔心。

Insert

建立一筆資料語法其實很簡單 db.collection.insert() 即可。

1
2
> db.movie.insert({'name':'Lord of Databases'})
WriteResult({ "nInserted" : 1 })

我們在 movie collection 內寫入名為 Lord of Databases 的資料。
可以看到系統回覆 nInserted:1 這是 number of inserted,也就是寫入數量為 1 筆。

接著來查看這筆資料長什麼樣子(查詢語法之後會講解)

1
2
3
> db.movie.find()
{ "_id" : ObjectId("612fb3ff761593c04673ee6f"), "name" : "Lord of Databases" }
>

如同之前文章所說,ObjectId 系統會自動幫你產生。

Collection 名稱?

回頭來看剛剛寫入資料的語法
db.movie.insert({'name':'Lord of Databases'})

這是我們直接指定 collection 為 movie,完整的語法應該是:
db.getCollection('movie').insert({'name':'Lord of Databases'})

getCollection 是不是就沒用了呢?
例如 collection 名稱為 action.movie,那會發生什麼事?(action.movie 為合法的命名)

1
2
3
4
5
> db.action.movie.insert({'name':'Mission Possible'})
WriteResult({ "nInserted" : 1 })
> db.action.movie.find()
{ "_id" : ObjectId("612fb60a761593c04673ee70"), "name" : "Mission Possible" }
>

嗯好~就不會發生什麼事。

insert() vs insertOne() vs insertMany()?

  • insertOne 顧名思義就是寫入一筆資料
1
2
3
4
5
> db.movie.insertOne({'name':'King of Databases'})
{
"acknowledged" : true,
"insertedId" : ObjectId("612fb6fe761593c04673ee71")
}
  • insertMany 顧名思義就是寫入多筆資料
1
2
3
4
5
6
7
8
9
10
11
> db.movie.insertMany([
{'name': 'Legend of MongoDB 1'},
{'name': 'Legend of MongoDB 2'}
])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612fb770761593c04673ee72"),
ObjectId("612fb770761593c04673ee73")
]
}

可以看得出來使用 insertOneinsertMany 都會回傳 ackowledged 以及 ObjectId,前者是用來確認 DB 確實寫入資料了,後者就是回傳寫入的 ObjectId,這方便商務邏輯的使用,一來確認完成,二來可以拿著 _id 做後續操作。

那如果我都不需要呢?

答案是還是可以用 insert() 來辦到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> db.movie.insert([{'name':'Test Movie 1'}, {'name': 'Test Movie 2'}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.movie.find()
{ "_id" : ObjectId("612fb3ff761593c04673ee6f"), "name" : "Lord of Databases" }
{ "_id" : ObjectId("612fb6fe761593c04673ee71"), "name" : "King of Databases" }
{ "_id" : ObjectId("612fb770761593c04673ee72"), "name" : "Legend of MongoDB 1" }
{ "_id" : ObjectId("612fb770761593c04673ee73"), "name" : "Legend of MongoDB 2" }
{ "_id" : ObjectId("612fb949761593c04673ee74"), "name" : "Test Movie 1" }
{ "_id" : ObjectId("612fb949761593c04673ee75"), "name" : "Test Movie 2" }
>

可以看到透過 insert() 也能夠辦到上述兩種,且寫入模式是 BulkWrite

Delete

MongoDB 刪除資料方式其實也和寫入差不多,語法有以下幾種

db.collection.deleteOne({})
db.collection.deleteMany({})

大括弧 { } 裡面是存放條件用的,如果不帶條件則是刪除第一筆 或是 全部刪除

不過我想通常應該是不會全刪除啦!要全刪除應該會改用 drop

  • 刪除全部資料:db.collection.deleteMany()
  • 刪除整個 Collection(包含 Index):db.collection.drop()

*註:有些地方會看到 remove 語法,這個語法已經被廢棄了,請不要再使用。

帶條件刪除資料

假設我們現在資料庫有這些資料…

1
2
3
4
5
6
7
8
film> db.movie.find()
[
{ _id: ObjectId("6130e75b1235fc1679ee0cb0"), name: 'aaa' },
{ _id: ObjectId("6130e88b2d393aea8c0c8e63"), a: 1 },
{ _id: ObjectId("6130e88b2d393aea8c0c8e64"), b: 2 },
{ _id: ObjectId("6130e8a72d393aea8c0c8e65"), c: 'aaa' },
{ _id: ObjectId("6130e8ae2d393aea8c0c8e66") }
]

我們想刪除最後一筆 { _id: ObjectId("6130e8ae2d393aea8c0c8e66") },它沒有任何欄位,但別忘記,還有預設的 key 欄位,所以可以這樣刪除

1
2
film> db.movie.deleteOne({_id:ObjectId('6130e8ae2d393aea8c0c8e66')})
{ acknowledged: true, deletedCount: 1 }

其實刪除欄位已經講完了,那再演示一個 deleteMany 的方法,假設我們要刪除 namedup 的資料:

1
2
3
4
5
6
7
8
9
10
11
12
13
film> db.movie.deleteMany({'name':'dup'})
{ acknowledged: true, deletedCount: 2 }
film> db.movie.find()
[
{ _id: ObjectId("6130e75b1235fc1679ee0cb0"), name: 'aaa' },
{ _id: ObjectId("6130e7951235fc1679ee0cb1"), name: 'bbb' },
{ _id: ObjectId("6130e7b22d393aea8c0c8e62"), name: 'c' },
{ _id: ObjectId("6130e88b2d393aea8c0c8e63"), a: 1 },
{ _id: ObjectId("6130e88b2d393aea8c0c8e64"), b: 2 },
{ _id: ObjectId("6130e8a72d393aea8c0c8e65"), c: 'aaa' },
{ _id: ObjectId("6130e9d8be17805b96148913"), "name" : "dup" }
{ _id: ObjectId("6130e9d8be17805b96148914"), "name" : "dup" }
]

可以看到 MongoDB 找到兩筆符合條件的,就刪除了。

劃重點

MongoDB 在針對一筆資料操作時,都是俱備原子性(Atomic)的,但像上述 insertMany 這種,它是操作 多筆,不俱備原子性,所以可能會和其他操作相互穿插,但每一筆的寫入還是有原子性喔!

  • 作者: MingYi Chou
  • 版權聲明: 轉載不用問,但請註明出處!本網誌均採用 BY-NC-SA 許可協議。