$match and update a certain key in object after $unwind in MongoDB

╄→гoц情女王★ 提交于 2020-01-25 09:03:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!