使用findOneAndUpdate $拉和填充不会更新或填充

这是我的数据:

{ "_id" : ObjectId("594e762b03cc52508686ceef"), "_members" : [ "59527bd5e521801bf07eab98", "594ecca47a699d1775c2a2db" ], } 

我想从_members删除_members

PostSchema:

 const PostsSchema = new Schema({ // ... _members: [{ type: Schema.Types.ObjectId, ref: 'user' }], // ... }) 

UserSchema:

 const UserSchema = new Schema({ // ... posts : [{ type: Schema.Types.ObjectId, ref: 'post' }], // ... }) 

查找和更新:

 let id = mongoose.mongo.ObjectID(req.params.id) let member = mongoose.mongo.ObjectID(req.params.member) let populateQuery = [ {path:'_members', select:'_id'} ] Post. findOneAndUpdate( {'_id' : id} , { $pull: { '_members': { '_id': member }} }, {'new': true} ). populate(populateQuery). exec( function (err, data) { res.send(data) } ); 

有趣的是,“人口”似乎只能通过在这种情况下将model选项指定为.populate()来工作。

你也只需要提供member直接$pull因为_id实际上不是一个属性,直到“填充”。 "_members"数组只是Post本身内的一个ObjectId值的数组。 所以直接提供input:

 Post.findOneAndUpdate( {'_id' : id} , { $pull: { '_members': member } }, {'new': true} ) .populate({path:'_members', select:'_id', model: 'user' }) .exec(function(err,post) { if (err) throw err; // or something res.send(post) }) 

或与承诺

 Post.findOneAndUpdate( {'_id' : id} , { $pull: { '_members': member } }, {'new': true} ) .populate({path:'_members', select:'_id', model: 'user' }) .then(post => res.send(post)) .catch(err => console.error(err)); // or something 

或者调用Model.populate()来代替:

 Post.findOneAndUpdate( {'_id' : id} , { $pull: { '_members': member } }, {'new': true} ).exec(function(err,post) { if (err) throw err; // or something Post.populate(post, {path:'_members', select:'_id', model: 'user' },function(err,post) { if (err) throw err; // or something res.send(post); // now populated } }) 

或者交替使用Promise:

 Post.findOneAndUpdate( {'_id' : id} , { $pull: { '_members': member } }, {'new': true} ) .then(post => Post.populate(post, {path:'_members', select:'_id', model: 'user' })) .then(post => res.send(post)) // also populated .catch(err => console.error(err)) // or whichever 

当你只是要求返回已经embedded到文档中的_id字段时,为什么要调用.populate()有些不确定,但这是另一种情况。 在model选项中,人口实际上是在这里发生的。


作为一个独立的示范:

 const async = require('async'), mongoose = require('mongoose'), Schema = mongoose.Schema; mongoose.Promise = global.Promise; mongoose.set('debug',true); mongoose.connect('mongodb://localhost/test'); const relSchema = new Schema({ c: String }); const testSchema = new Schema({ a: String, b: [{ type: Schema.Types.ObjectId, rel: 'Rel' }] }) const Test = mongoose.model('Test', testSchema); const Rel = mongoose.model('Rel', relSchema); function log(data) { console.log(JSON.stringify(data, undefined, 2)) } async.series( [ (callback) => async.each(mongoose.models,(model,callback) => model.remove({},callback),callback), (callback) => async.waterfall( [ (callback) => Rel.create([{ c: 2 },{ c: 3 },{ c: 4 }],callback), (rels,callback) => Test.create({ a: 1, b: rels },(err,test) => { if (err) callback(err); log(test); callback(err,test.b.slice(1,3)) }), (rels,calback) => Test.findOneAndUpdate( { 'a': 1 }, { '$pull': { 'b': rels[0] } }, { 'new': true } ) .populate({ path: 'b', model: 'Rel' }) .exec((err,test) => { if (err) callback(err); log(test); callback(err); }) ], callback ) ], (err) => { if (err) throw err; mongoose.disconnect(); } ) 

而输出:

 Mongoose: tests.remove({}, {}) Mongoose: rels.remove({}, {}) Mongoose: rels.insert({ c: '2', _id: ObjectId("595714579afd8860e56d2ec7"), __v: 0 }) Mongoose: rels.insert({ c: '3', _id: ObjectId("595714579afd8860e56d2ec8"), __v: 0 }) Mongoose: rels.insert({ c: '4', _id: ObjectId("595714579afd8860e56d2ec9"), __v: 0 }) Mongoose: tests.insert({ a: '1', _id: ObjectId("595714579afd8860e56d2eca"), b: [ ObjectId("595714579afd8860e56d2ec7"), ObjectId("595714579afd8860e56d2ec8"), ObjectId("595714579afd8860e56d2ec9") ], __v: 0 }) { "__v": 0, "a": "1", "_id": "595714579afd8860e56d2eca", "b": [ "595714579afd8860e56d2ec7", "595714579afd8860e56d2ec8", "595714579afd8860e56d2ec9" ] } Mongoose: tests.findAndModify({ a: '1' }, [], { '$pull': { b: ObjectId("595714579afd8860e56d2ec8") } }, { new: true, upsert: false, remove: false, fields: {} }) Mongoose: rels.find({ _id: { '$in': [ ObjectId("595714579afd8860e56d2ec7"), ObjectId("595714579afd8860e56d2ec9") ] } }, { fields: {} }) { "_id": "595714579afd8860e56d2eca", "a": "1", "__v": 0, "b": [ { "_id": "595714579afd8860e56d2ec7", "c": "2", "__v": 0 }, { "_id": "595714579afd8860e56d2ec9", "c": "4", "__v": 0 } ] }