Push value of existing field as an element of new list

I’m trying to add the string value of one field (special_tag), if exist, as an element of a new list value (special_tags)

db.ip_reports.updateMany(
    { "special_tag": {"$ne": null}  },
    { "$push": { "$expr": {"special_tags": "$special_tag"  } } }
);

and getting the following error

"errmsg" : "The dollar ($) prefixed field '$expr' in '$expr' is not valid for storage."

Hello @Yurii_Cherkasov, welcome to the MongoDB Community forum!

To update a field using another field’s value you need to use Updates with Aggregation Pipeline. With the pipeline you get to use the Aggregation Pipeline Operators (you will not be using the $push or the $expr operators with this feature.). Note that this feature is available with MongoDB v4.2 or later only.

1 Like

@Prasad_Saya
Thank you, I read about the Aggregation Framework and even started the related course at Mongo University. But even after numerous attempts and on the 2nd Chapter of the course, I can’t find the example I need. I understand I need to use $addField to extend my document. But what if I don’t want to add their projection of any existing value, but want to create a list and push this value?

When using a Pipeline to update a collection, you need to use the $set stage (instead of the $addFields). Here is what I think you are trying to accomplish:

db.ip_reports.updateMany(
  { "special_tag": { "$ne": null}  },
  [
    { 
      $set: { 
          special_tags : { $concatArrays: [ "$special_tags",  [ "$special_tag" ] ] }
      }
    } 
  ]
);

If you are not sure if the special_tags array field exists or not, then use this, instead of the above assignment:

special_tags : { $concatArrays: [ { $ifNull: [ "$special_tags", [ ] ] }, "$special_tag" ] }

1 Like