Mongodb moving value from NumberInt to NumberLong

mongodb

We are trying to preallocate documents in a collection. Usually NumberInt for our values is sufficient. When we get 1million writes into that document (it is one doc per day time series, so 1 million is possible), then the value moves from NumberInt to NumberLong.

We are planning to disable padding, so any single byte movement will move the document.

The question is, whether mongodb will move the document if the NumberInt changes to NumberLong

Best Answer

If you are using MongoDB 3.0 + MMAPv1 with noPadding allocation (aka "exact fit"), then the document will have to move if you change from 32-bit ints (4 bytes) to 64-bit longs (8 bytes). With noPadding there is no extra space available to store more bytes, so you should start with NumberLongs to avoid expected document growth.

The question is, whether mongodb will move the document if the NumberInt changes to NumberLong

You can confirm the outcome via the database profiler. Here's a quick run in the 3.0.7 mongo shell:

// Drop test collection
db.mycollection.drop();

// Create new test collection with noPadding (exact-fit allocation)
db.createCollection("mycollection", { noPadding: true });

// Enabling profiling of all operations
db.setProfilingLevel(2)

// Insert a document with a 32-bit int
db.mycollection.insert({ _id: 'nopadding', value: NumberInt(42) });

// Update document to have a 64-bit int
db.mycollection.update({ _id: 'nopadding' }, { $set: { value: NumberLong(10000000) }});

// Disable profiling
db.setProfilingLevel(0);

// Check if our update operation resulted in a move
db.system.profile.find({op:'update', 'query._id': 'nopadding', moved: true}).count()
1