[MongoDB] Update Operators in mongoDB

Các toán tử update trong mongo cũng như các database khác giúp bạn định nghĩa lại bản ghi (or document) hoặc nhiều bản ghi (or documents). Chúng ta cùng xem xét mongoDB có những kiểu cập nhật dữ liệu nào và cú pháp của nó ra sao nhé :D

0. Cú pháp chung

1
2
3
4
5
6
7
8
9
10
11
12
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)

Giải thích qua về các tham số:

  • query: điều kiện lựa chọn document để update
  • update: Cách thức cập nhật lại document (sẽ đề cập phần dưới)

Các tùy chọn trong update:

  • upsert: mặc định false. Nếu upsert:true, nó sẽ thêm 1 doucment nếu khi update, không document nào trùng với query. Có thể sử dụng nó kết hợp với $setOnInsert

Note: nếu query với index hoặc trường nào đó duy nhất, tránh sử dụng upsert:true để bị lặp bản ghi @@

  • multi: update nhiều document hay không?
  • writeConcern: méo hiểu
  • collation: cho phép người dùng chỉ định ra các rule ngôn ngữ cụ thể cho việc so sánh string, đơn giản như là rule chữ hoa chữ thường hay trọng âm
  • arrayFilters: xác định phần tử nào trong mảng sẽ được update
  • hint: xác định index được sử dụng hỗ trợ query. Tùy chọn này được thêm từ phiên bản Mongo 4.2 liên quan đến Index

1. Các loại update trong mongo

1.1. Cập nhật lại các trường của 1 document

Nếu bạn muốn cập nhật 1 vài trường trong Document đã tồn tại, bạn hãy sử dụng các toán tử update được nhắc đề cập ở phần sau:

1
2
3
4
5
db.collection.update(
<query>,
{ $set: { status: "D" }, $inc: { quantity: 2 } },
...
)

1.2. Thay thế hoàn toàn document

Nếu bạn muốn thay thế hoàn toàn document đã có bằng 1 document mới tính với các trường mới, sử dụng cú pháp chỉ có field:value

1
2
3
4
5
db.collection.update(
<query>,
{ item: "XYZ123", stock: 10, info: { publisher: "2255", pages: 150 }, tags: [ "baking", "cooking" ] }
...
)

Lưu ý:

- Phép thay thế này sẽ thay thế toàn bộ các trường cũ bằng các trường mới được set vào (trừ _id)
- Không thể thay thế được nhiều document

1.3. Update với Aggregation Pipeline

1
2
3
4
5
6
7
8
db.collection.update(
<query>,
[
{ $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } },
{ $unset: [ "misc1", "misc2" ] }
]
...
)

Note: The $set and $unsetused in the pipeline refers to the aggregation stages $set and $unset respectively, and not the update operators $set and $unset.

2. Các toán tử update

Reference: https://docs.mongodb.com/manual/reference/operator/update/

2.1. Các toán tử update với trường (Field Update Operators)

Tên Mô tả
$currentDate Set giá trị của 1 trường bằng ngày hiện tại, có 2 tùy chọn là kiểu ngày (Date) hoặc Timestamp
$inc Tăng giá trị của 1 trường với 1 giá trị xác định
$min Chỉ cập nhật trường đó nếu giá trị đó nhỏ hơn giá trị đã tồn tại.
$max Tương tự $min
$mul Nhân giá trị của 1 trường với 1 giá trị
$rename Đổi tên 1 trường
$set Sets the value of a field in a document.
$setOnInsert Set giá trị của 1 trường nếu kết quả của phép update là 1 phép thêm document. Sẽ không có ảnh hưởng đến các phép update mà sửa đổi documents đã tồn tại.
$unset Removes the specified field from a document.

$min

Ví dụ document hiện tại:

1
{ _id: 1, highScore: 800, lowScore: 200 }

Giá trị lowScore hiện tại trong document đang là 200. Toán tử $mindưới đây so sánh 200 với giá trị xác định 150 và cập nhật giá trị lowScore là 150 vì 150 < 200
1
db.scores.update( { _id: 1 }, { $min: { lowScore: 150 } } )

Và kết quả ta có:
1
{ _id: 1, highScore: 800, lowScore: 150 }

Toán tử tiếp theo lại không có ảnh ưởng gì vì 150 < 250
1
db.scores.update( { _id: 1 }, { $min: { lowScore: 250 } } )

Kết quả là:
1
{ _id: 1, highScore: 800, lowScore: 150 }` <br>(không ảnh hưởng :D)

Note: $min có thể được sử dụng để so sánh cả kiểu Date

$rename

Ta xem xét document hiện tại như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{ 
"_id": 1,
"alias": [ "The American Cincinnatus", "The American Fabius" ],
"mobile": "555-555-5555",
"nmae": { "first" : "george", "last" : "washington" }
},
{
"_id": 2,
"alias": [ "My dearest friend" ],
"mobile": "222-222-2222",
"nmae": { "first" : "abigail", "last" : "adams" }
},
{
"_id": 3,
"alias": [ "Amazing grace" ],
"mobile": "111-111-1111",
"nmae": { "first" : "grace", "last" : "hopper" }
}

Trường nmae đang bị viết sai chính tả, chúng ta đổi lên tên thôi

1
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )

Note:

- Nó update được cả tên trường trong Embedded Document
- Nếu update tên 1 trường không tồn tại, nó sẽ không làm gì cả :D

2.2. Các toán tử update với mảng (Array Update Operators)

Update Operators

Tên toán tử Mô tả
$ Cập nhật phần tử đầu tiên trong mảng trùng với điều kiện truy vấn
$[] Cập nhật tất cả các phần tử trong mảng trùng với điều kiện truy vấn
$[] Cập nhật tất cả các phần tử trong mảng, cái mà trùng với điều kiện arrayFilters (trong tùy chọn update) và điều kiện truy vấn
$addToSet Thêm phần tử vào 1 mảng nếu nó chưa tồn tại (dùng toán tử này để các phần tử trong mảng là duy nhất)
$pop Xóa phần tử đầu tiên hoặc cuối cùng của 1 mảng
$pull Xóa toàn bộ phần tử của mảng trùng với điều kiện xác định
$push Thêm 1 thành phần vào 1 mảng
$pullAll Xóa tất cả các giá trị phù hợp với điều kiện từ 1 mảng

Update Operator Modifiers

Tên toán tử Mô tả
$each Sửa toán tử $push và $addToSet để thêm nhiều item vào mảng update
$position Chỉnh sửa toán tử $push để xác định vị trí các thành phần được thêm vào mảng
$slice Chỉnh sửa toán tử $push để giới hạn kích thước được thêm vào mảng
$sort Chỉnh sửa toán tử $push để sắp xếp lại các document được lưu trữ trong mảng

Tài liệu tham khảo

Author

Ming

Posted on

2019-09-08

Updated on

2021-04-10

Licensed under

Comments