0

I have a mongodb collection with around 4-5 million documents. It have a field with name "role": "admin". What I want to do is to convert all the roles to array i.e "role": ["admin"].

I prefer not to use forEach loop. Please help me with this. I am a bit new to mongodb.

old documents

{
  "role": "admin"
}
{
  "role": "mod"
}

to new documents

{
  "role": ["admin"]
}
{
  "role": ["mod"]
}
3
  • Refer to this link->stackoverflow.com/questions/7401394/… Commented Jan 10, 2017 at 8:25
  • Yah, saw that post earlier but dont want to use db.eval as it will lock down the db till that completes itself Commented Jan 10, 2017 at 8:32
  • 1
    I don't think we can do this without using forEach. Why do you prefer not to you use forEach ? Commented Jan 10, 2017 at 9:12

1 Answer 1

2

you could do this using aggregation like this (directly from shell) :

db.collection.aggregate([
  {$group: {
     _id: "$_id",
     role: {$push: "$role"}
    }
  },
   {$out: "newCollection"}
])

the $group stage will generate these results:

{ "_id" : ObjectId("5874a728cf097894d781d7f0"), "role" : [ "mod" ] }
{ "_id" : ObjectId("5874a724cf097894d781d7ef"), "role" : [ "admin" ] }

and the $out will write it to a specific collection ( can be a new collection or your existing one).

Be carefull when overwritting an existing collection with $out as you can't undo the operation

Sign up to request clarification or add additional context in comments.

2 Comments

Yah your way is the way I want, but i have many additional fields too along with role, it aint working for that. Can u help by modifying a bit?
@iamsaksham sure, if you want to keep the other fields, just add them in the $group stage like this : "fieldname": { $first: "$fieldname"}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.