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:
-
$addFieldsvà bí danh của nó$set -
$projectvà bí danh của nó$unset -
$replaceRootvà 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 }
);