Add a field into capped collection in MongoDB

1.1k Views Asked by At

I created a capped collection to store my log data with few fields. Due to some requirement I wanted to add an additional field named "createAt" in this collection.

db.myLogs.update({},{$set: {"createAt":new Date()}})

This is throwing below error:

WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 10003,
                "errmsg" : "Cannot change the size of a document in a capped collection: 39 != 57"
        }
})

How can I add a few field into capped collection?

1

There are 1 best solutions below

1
On BEST ANSWER

Simple answer

As mongod tells you, you can't. As does the documentation:

If the update operation causes a document to grow beyond the document’s original size, the update operation will fail.

Slightly more sophisticated answer

If the field isn't mandatory, simply add the new documents with the field and leave the old documents as they are, using a sensible default value for the documents which do not have the field.

If you really need to do it

  1. Stop reading from and writing to the capped collection
  2. Copy the documents from the capped collection to a temporary collection
  3. Change the documents as needed in the temporary collection
  4. Drop and recreate the capped collection
  5. Read the documents from the temporary collection in the desired order and insert them into the recreated capped collection.

After you did "1.", you can use something like this for "2." on the shell:

var bulk = db.temp.initializeOrderedBulkOp();
var counter = 0;

db.capped.find().forEach(

  function(doc){
    bulk.insert(doc);

    // In case you have a lot of documents in
    // your capped collection, it makes sense
    // to do an intermediate execute
    if( ++counter % 10000 == 0){
      bulk.execute();
      bulk = db.temp.initializeOrderedBulkOp();
    }

  }
);
// execute the remainder
bulk.execute() 

This should be easily adaptable for "5."