Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move Mongo Embeded Document into Own Collection

Can someone point me in the right direction, i have a Collection (Forms) each Form has an embedded document array (Responses). Responses for each form have gotten massive and in hindsight embedding them was a bad idea (mongo documents including embedded have a maximum size limit).

Is there a way i can quickly and easily move all of these embedded Responses into their own collection? is there such a thing like the old SQL select into? I have had a look around in rails console but it is inaccessible with so many embedded documents, so i imagine it'll have to be a complex find and insert query in the mongo console? (just guessing there)

My Model is fixed but this migration (and the mongo docs) are stumping me.

TIA Dougle

like image 541
Question Mark Avatar asked Mar 21 '11 16:03

Question Mark


People also ask

What are nested documents MongoDB?

MongoDB provides you a cool feature which is known as Embedded or Nested Document. Embedded document or nested documents are those types of documents which contain a document inside another document.

When should be embedded one document within another in MongoDB?

An embedded, or nested, MongoDB Document is a normal document that's nested inside another document within a MongoDB collection. Embedded documents are particularly useful when a one-to-many relationship exists between documents.


1 Answers

So here's a start... This is in the mongo shell

db.questions.insert({name:"jwo", responses:[{question:"your name?", answer:"yomamma"}, {question:"your name?", answer:"pappa"}]});

This created a document json structure like so:

> db.questions.findOne();
{
    "_id" : ObjectId("4d877e89b75dc42c4709278d"),
    "name" : "jwo",
    "responses" : [
        {
            "question" : "your name?",
            "answer" : "yomamma"
        },
        {
            "question" : "your name?",
            "answer" : "pappa"
        }
    ]
}

Now loop through the responses, and set their question_id with the questions' _id, and then insert it into the new responses collection

> for(i=0; i<question.responses.length; ++i){
... question.responses[i].question_id = question._id;   
... db.responses.insert(question.responses[i]);                                                                      
... }

> db.responses.findOne();
{
    "_id" : ObjectId("4d878059b75dc42c4709278e"),
    "question" : "your name?",
    "answer" : "yomamma",
    "question_id" : ObjectId("4d877e89b75dc42c4709278d")
}

You'll want to change the db.questions.findOne to find all of them and loop over. If this does take a while, you may need to switch to a map-reduce function.

like image 97
Jesse Wolgamott Avatar answered Oct 04 '22 04:10

Jesse Wolgamott