mongodbaggregatefindandmodify

mongodb | How to update(findandmodify) after aggregate


I want to update some of the values according to the result after query execution.


What I want to +1 the "comment_sort" value if the condition is true.

Condition : If "comment_group" is 1 and "comment_sort" is greater than 0


Original DataBase is..

{
    "_id" : ObjectId("5bc984ef8e798ccb0309ef13"),
    "post_no" : 56,
    "username" : "a@a.aa",
    "nickname" : "nickNameSuccess",
    "post_content" : "56",
    "post_title" : "56"
    "comment" : [ 
        {
            "comment_no" : 238,
            "comment_sort" : 1,  // (+1) "comment_sort" : 2 
            "comment_depth" : 0,
            "comment_group" : 1
        }, 
        {
            "comment_no" : 240,
            "comment_sort" : 2, // (+1) "comment_sort" : 3
            "comment_depth" : 1,
            "comment_group" : 1
        }, 
        {
            "comment_no" : 235,
            "comment_sort" : 1,
            "comment_depth" : 0,
            "comment_group" : 2
        }, 
        {
            "comment_no" : 237,
            "comment_sort" : 2,
            "comment_depth" : 0,
            "comment_group" : 2
        }
    ]
}


Query is..

db.getCollection('post').aggregate([
    {"$match" : {"post_no": 56}},
    { "$project": {
    "comment": {
      "$map": {
        "input": "$comment",
        "in": {
          "comment_no": "$$this.comment_no",
          "comment_group": "$$this.comment_group",
          "comment_sort": "$$this.comment_sort",
          "comment_depth": "$$this.comment_depth"
        }
      }
    }
  }},
  { "$unwind": '$comment' },
  {"$match" : {"comment.comment_group": 1}},
  {"$match" : {"comment.comment_sort": {"$gt":0}} },
//   { $group: { _id: null, comment_sort: { $max: "$comment.comment_sort" }}}
])


Result is..

{
    "_id" : ObjectId("5bc984ef8e798ccb0309ef13"),
    "comment" : {
        "comment_no" : 238,
        "comment_group" : 1,
        "comment_sort" : 1,
        "comment_depth" : 0
    }
},
{
    "_id" : ObjectId("5bc984ef8e798ccb0309ef13"),
    "comment" : {
        "comment_no" : 240,
        "comment_group" : 1,
        "comment_sort" : 2,
        "comment_depth" : 1
    }
}


From this result, I want to increase(+1) only the value of 'comment_sort'.

(ex. 1 --> 2, 2 --> 3)

How can I improve the query?

I would like advice.

Regards.


Solution

  • You cannot update your documents from aggregagtion pipeline ($out stage will replace your whole collection). However, you can translate your aggregation to an update query with positional filters to update matching element of your array. Here's the query :

    db.getCollection('post').update(
      {post_no:56},
      {$inc:{"comment.$[com].comment_sort":1}},
      {arrayFilters: [ {$and:[{"com.comment_group": 1},{"com.comment_sort": {"$gt":0}} ]}]  }
    )
    

    Explanations :

    Hope it helps.

    EDIT No kind of unwinding is performed while updating, so query result will indicate 1 document updated. But 2 array elements will be incremented. (In this case of course)