Với MongoDB 4.2 và mới hơn, phương thức cập nhật hiện có thể lấy tài liệu hoặc một đường dẫn tổng hợp trong đó các giai đoạn sau có thể được sử dụng:
-
$addFields
và bí danh của nó$set
-
$project
và bí danh của nó$unset
-
$replaceRoot
và bí danh của nó$replaceWith
.
Được trang bị ở trên, thao tác cập nhật của bạn với đường dẫn tổng hợp sẽ ghi đè các thẻ tags
bằng cách nối các thẻ tags
đã lọc mảng và một mảng được ánh xạ của danh sách đầu vào với một số tra cứu dữ liệu trong bản đồ:
Để bắt đầu, biểu thức tổng hợp lọc mảng thẻ sử dụng $filter
và nó như sau:
const myTags = ["architecture", "blabladontexist"];
{
"$filter": {
"input": "$tags",
"cond": {
"$not": [
{ "$in": ["$$this.t", myTags] }
]
}
}
}
tạo ra mảng tài liệu đã lọc
[
{ "t" : "contemporary", "n" : 2 },
{ "t" : "creative", "n" : 1 },
{ "t" : "concrete", "n" : 3 }
]
Bây giờ phần thứ hai sẽ là dẫn xuất mảng khác sẽ được nối với phần trên. Mảng này yêu cầu $map
qua myTags
mảng đầu vào dưới dạng
{
"$map": {
"input": myTags,
"in": {
"$cond": {
"if": { "$in": ["$$this", "$tags.t"] },
"then": {
"t": "$$this",
"n": {
"$sum": [
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
},
1
]
}
},
"else": { "t": "$$this", "n": 0 }
}
}
}
}
$map
ở trên
về cơ bản lặp lại mảng đầu vào và kiểm tra từng phần tử xem nó có nằm trong các thẻ tags
không mảng so sánh t
, nếu nó tồn tại thì giá trị của n
trường của subocument trở thành n
hiện tại của nó valueexpression với
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
}
nếu không, hãy thêm tài liệu mặc định với giá trị n là 0.
Nhìn chung, hoạt động cập nhật của bạn sẽ như sau
Thao tác cập nhật cuối cùng của bạn trở thành:
const myTags = ["architecture", "blabladontexist"];
db.getCollection('coll').update(
{ "_id": "1234" },
[
{ "$set": {
"tags": {
"$concatArrays": [
{ "$filter": {
"input": "$tags",
"cond": { "$not": [ { "$in": ["$$this.t", myTags] } ] }
} },
{ "$map": {
"input": myTags,
"in": {
"$cond": [
{ "$in": ["$$this", "$tags.t"] },
{ "t": "$$this", "n": {
"$sum": [
{ "$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
] },
1
]
} },
{ "t": "$$this", "n": 0 }
]
}
} }
]
}
} }
],
{ "upsert": true }
);