Trong MongoDB, toán tử $push được sử dụng để nối một giá trị đã chỉ định vào một mảng. Nếu trường được đề cập không có trong tài liệu để cập nhật, toán tử $push sẽ thêm trường đó dưới dạng trường mới và bao gồm giá trị được đề cập làm thành phần của nó. Nếu trường cập nhật không phải là trường kiểu mảng thì thao tác không thành công
Tại thời điểm cập nhật nếu bản thân giá trị là một mảng, toán tử $push sẽ nối toàn bộ mảng dưới dạng một phần tử
Nếu bạn muốn thêm từng phần tử của giá trị một cách riêng biệt, toán tử $push có thể được sử dụng với công cụ sửa đổi $each
cú pháp
db.collection.update[ ,{ $push: { : } }]
Thông số
TênMô tảtrường tên của cột hoặc trường vào tài liệu. giá trị. Đây là những giá trị được chỉ định cho các trường hoặc cột. truy vấn Truy vấn có thể là một biểu thức hoặc điều kiện hoặc tiêu chí
Bộ sưu tập mẫu "sinh viên"
{
"_id" : 1,
"sem" : 1,
"subjects" : [
"phys",
"chem",
"maths",
"gkn",
"stat",
"astro"
],
"achieve" : [
70,
87,
90,
90,
65,
81
]
}
Ví dụ về toán tử MongoDB $push
Nếu chúng ta muốn nối 95 vào trường mảng đạt được đối với các đối tượng điều kiện là "gkn", có thể sử dụng lệnh mongodb sau -
> db.student.update[ { "subjects" : "gkn" },{ $push: { "achieve": 95 } }];
Ở đây trong ví dụ trên, công cụ sửa đổi $each đã được sử dụng để nối nhiều phần tử 77,49,83 vào mảng đạt được khớp với điều kiện đối tượng bằng "gkn"
Thao tác này cập nhật tài liệu được nhúng đầu tiên phù hợp với tiêu chí, cụ thể là tài liệu được nhúng thứ hai trong mảng
{ _id: 4, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 6 }, { grade: 90, mean: 85, std: 3 } ] }
参见
db. thu thập. cập nhật[] , db. thu thập. findAndModify[] , $elemMatch[]
← Toán tử cập nhật mảng $addToSet →
© MongoDB, Inc 2008-2017. MongoDB, Mongo và logo chiếc lá là các nhãn hiệu đã đăng ký của MongoDB, Inc
Nếu bạn đã từng làm việc với MongoDB trước đây thì rất có thể bạn đã lưu trữ các tài liệu phụ trong mảng, đây là một trong nhiều lý do khiến MongoDB tỏa sáng hơn các cơ sở dữ liệu truyền thống khác
cách tiếp cận gật gù
Tuy nhiên, nếu bạn có một tài liệu mà bạn muốn chèn một tài liệu con vào một mảng khi nó không tồn tại, hoặc cập nhật toàn bộ tài liệu trong mảng khi nó tồn tại thì rất có thể bạn sẽ kéo mục đó ra khỏi mảng
// Insert a test item document
db.items.insertOne[{
"_id" : ObjectId["623ded6e1ce9aa98b37ce86a"],
"items": [
{ "_id": 1, "content": "aaa"},
{ "_id": 2, "content": "bbb"},
{ "_id": 3, "content": "ccc"},
]
}]
// Pull the array item which we want to update
db.items.updateOne[
{ "_id" : ObjectId["623ded6e1ce9aa98b37ce86a"]},
{
"$pull": {
"items": { "_id": 2 }
}
}
]
// Push the updated item back in to the array [we're updating content to "zzz"]
db.items.updateOne[
{ "_id" : ObjectId["623ded6e1ce9aa98b37ce86a"]},
{
"$push": {
"items": {
"_id": 2, "content": "zzz"
}
}
}
]
// Check final document
db.items.find[]
[
{
_id: ObjectId["623ded6e1ce9aa98b37ce86a"],
items: [
{ _id: 1, content: 'aaa' },
{ _id: 3, content: 'ccc' },
{ _id: 2, content: 'zzz' }
]
}
]
Điều này khá ồn ào và nếu ai đó tìm nạp tài liệu trong khi cập nhật nửa chừng thì họ cũng sẽ nhận được chế độ xem tài liệu không nhất quán với mục có id là 2 bị thiếu. Tuy nhiên, chúng tôi có thể khắc phục sự cố với sự không nhất quán bằng cách bắt đầu giao dịch và hoàn thành 2 thao tác cùng nhau
giao dịch
Đoạn mã dưới đây cho thấy 2 hoạt động được bao bọc trong một giao dịch
// Start a session
var session = db.getMongo[].startSession[ { readPreference: { mode: "primary" } } ];
// Start a transaction
session.startTransaction[ { readConcern: { level: "local" }, writeConcern: { w: "majority" } } ];
try {
var items = session.getDatabase["test"].items;
// Pull the array item which we want to update
items.updateOne[
{ "_id" : ObjectId["623ded6e1ce9aa98b37ce86a"]},
{
"$pull": {
"items": { "_id": 2 }
}
}
]
// Push the updated item back in to the array [we're updating content to "zzz"]
items.updateOne[
{ "_id" : ObjectId["623ded6e1ce9aa98b37ce86a"]},
{
"$push": {
"items": {
"_id": 2, "content": "zzz"
}
}
}
]
// Commit the transaction using write concern set at transaction start
session.commitTransaction[];
} catch [error] {
// Abort transaction on error
session.abortTransaction[];
throw error;
}
session.endSession[];
Đây là một cách tuyệt vời để thực hiện nhiều thao tác trên một tài liệu, tuy nhiên, nó yêu cầu phải có MongoDB 4. 0 đang chạy trong bộ bản sao hoặc MongoDB 4. 2 nếu dữ liệu của bạn được phân vùng trên nhiều phân đoạn
Cập nhật đường ống tổng hợp
Một cách khác là sử dụng thao tác cập nhật với đường dẫn tổng hợp [Điều này cũng yêu cầu MongoDB v4. 2], điều này cho phép một thao tác cập nhật duy nhất mà không cần bất kỳ giao dịch nào
Bản cập nhật bên dưới với quy trình tổng hợp rất giống với thao tác trên, chúng tôi đang sử dụng giai đoạn tổng hợp $addFields
để tiếp tục thay thế trên đầu trường myItems
db.items.updateOne[
{ "_id" : ObjectId["6176d58d636041dbac68233c"]},
[
{
$addFields: {
"myItems": {
$filter: {
input: "$myItems",
as: "item",
cond: { $ne: [
"$$item.id",
2
]
}
}
}
}
},
{
$addFields: {
"myItems": { $concatArrays: [ "$myItems",
[
{
"id": 2,
"extraProps": true,
"content": "Hello World"
}
]
]
}
}
}
]
]
Giai đoạn $addFields
đầu tiên loại bỏ tài liệu khỏi mảng dựa trên một điều kiện nhất định bằng cách sử dụng toán tử
{
"_id" : 1,
"sem" : 1,
"subjects" : [
"phys",
"chem",
"maths",
"gkn",
"stat",
"astro"
],
"achieve" : [
70,
87,
90,
90,
65,
81
]
}
0 và sau đó giai đoạn $addFields
thứ hai sau đó nối thêm tài liệu mới bằng cách sử dụng toán tử {
"_id" : 1,
"sem" : 1,
"subjects" : [
"phys",
"chem",
"maths",
"gkn",
"stat",
"astro"
],
"achieve" : [
70,
87,
90,
90,
65,
81
]
}
2Cách tốt nhất?
Giống như hầu hết mọi thứ trong quá trình phát triển phần mềm, không có cách nào tốt nhất để giải quyết vấn đề, quy trình tổng hợp cập nhật có thể trở nên phức tạp nhưng ít trò chuyện hơn và không yêu cầu giao dịch. Tuy nhiên, cách tiếp cận giao dịch có thể làm cho mã của bạn dễ hiểu hơn, nhưng sau đó có phí giao dịch và cũng yêu cầu một bộ bản sao để phát triển cục bộ