问题
I have documents like the following one:
{
"_id" : ObjectId("5dc027d38da295b969eca67c"),
"emp_no" : 10031,
"salaries" : [
{
"salary" : 40000,
"from_date" : "1991-09-01",
"to_date" : "1992-08-31"
},
{
"salary" : 40859,
"from_date" : "1992-08-31",
"to_date" : "1993-08-31"
},
{
"salary" : 41881,
"from_date" : "1993-08-31",
"to_date" : "1994-08-31"
}
]
}
As a goal I need to increment salary
by 1000 for every object that has from_date
key in a range of 1985-01-01 - 1985-12-31.
So far i came up with this query:
db.emp_salaries.aggregate( [
{ $unwind: "$salaries" },
{ $match: {
"salaries.from_date": {$gte: "1985-01-01"},
"salaries.from_date": {$lte: "1985-12-13"},
} }
] )
but i can't target from_date
key this way. I have no idea how to do this. This $match
seems to be totally ignored. I've heard about an operator which can automatically target such a key regardless of its position from the beginning of an object, but couldn't find it back.
How do I target this key and perform an update on salary
?
回答1:
The filtered positional operator $[<identifier>]
identifies the array elements that match the arrayFilters
conditions for an update operation. The following query will update the sub-document fields in the array with the matching condition.
db.arr_upd.updateMany(
{ },
{ $inc: { "salaries.$[elem].salary" : 1000 } },
{ arrayFilters: [ { $and: [ { "elem.from_date": { $gte: "1991-09-01" } }, { "elem.from_date": { $lte: "1992-08-31" } } ] } ] }
)
This will update the first two elements' salary
values to 41000
and 41859
, respectively (for the example document shown in the question post).
回答2:
Try to use ISODate instead of regular strings for the date field. It probably compare it by it's string value and not as date
回答3:
It can be done using a shell command.
db.emp_salaries.updateMany({
'salaries.from_date': {
$gte: '1985-01-01',
$lte: '1985-12-13'
}
},
{
$inc: {'salaries.$.salary': 1000}
})
来源:https://stackoverflow.com/questions/58856417/match-and-update-a-certain-key-in-object-after-unwind-in-mongodb