Sebastian Nowak
Sebastian Nowak

Reputation: 5717

MongoDB $pull efficiency

Let's assume following schema

var schema = new mongoose.Schema({
    data: { type: [Number] }
});
schema.index({ _id: 1, data: 1 });
var model = mongoose.model('Test', schema);

How efficient is $pull operator when removing entries from doc.data?

model.update({ _id: someId }, { $pull: { data: { $lte: 123 } } }).exec();

Will it use the index and run in O(log n + m) complexity, where n is the number of elements in data and m the number of removed elements? Or does it have to scan whole array?

And what's the complexity of removing an element after Mongo finds it? Is it O(1), O(log n) or O(n) as it has to shift other items?

Upvotes: 2

Views: 427

Answers (1)

JohnnyHK
JohnnyHK

Reputation: 312045

The collection's indexes are only used for the doc finding part of the update, not the update itself.

So the built-in index on _id will be used to find the document, but the $pull update will require the whole data array be read and scanned against the {$lte: 123} query: O(n).

The index you added on { _id: 1, data: 1 } would only be used if you also included data in your actual query as:

model.update({_id: someId, data: {$lte: 123}}, {$pull: {data: {$lte: 123}}}).exec();

But that would only provide a benefit in the case where data contained no elements with a value <= 123 by short-circuiting the update as the doc would no longer match the criteria. It still wouldn't be used to find the data elements for the $pull itself.

Upvotes: 3

Related Questions