diff --git a/db/commands/find_and_modify.cpp b/db/commands/find_and_modify.cpp index 23f672c6f6fff..2856ab3d3f143 100644 --- a/db/commands/find_and_modify.cpp +++ b/db/commands/find_and_modify.cpp @@ -53,6 +53,13 @@ namespace mongo { BSONObj fieldsHolder (cmdObj.getObjectField("fields")); const BSONObj* fields = (fieldsHolder.isEmpty() ? NULL : &fieldsHolder); + Projection projection; + if (fields) { + projection.init(fieldsHolder); + if (!projection.includeID()) + fields = NULL; // do projection in post-processing + } + BSONObj out = db.findOne(ns, q, fields); if (out.isEmpty()) { if (!upsert) { @@ -131,6 +138,11 @@ namespace mongo { } } + if (!fieldsHolder.isEmpty() && !fields){ + // we need to run projection but haven't yet + out = projection.transform(out); + } + result.append("value", out); return true; diff --git a/db/projection.h b/db/projection.h index fd3b85629c5c1..b5e0a0c42890c 100644 --- a/db/projection.h +++ b/db/projection.h @@ -94,6 +94,8 @@ namespace mongo { */ KeyOnly* checkKey( const BSONObj& keyPattern ) const; + bool includeID() const { return _includeID; } + private: /** diff --git a/jstests/find_and_modify2.js b/jstests/find_and_modify2.js index 108fc0fff5ceb..2c8ab5b3bb607 100644 --- a/jstests/find_and_modify2.js +++ b/jstests/find_and_modify2.js @@ -8,3 +8,9 @@ assert.eq(out, {_id:1, i:1}); out = t.findAndModify({update: {$inc: {i:1}}, fields: {i:0}}); assert.eq(out, {_id:1, j:0}); + +out = t.findAndModify({update: {$inc: {i:1}}, fields: {_id:0, j:1}}); +assert.eq(out, {j:0}); + +out = t.findAndModify({update: {$inc: {i:1}}, fields: {_id:0, j:1}, 'new': true}); +assert.eq(out, {j:0});