2017-06-30 91 views
1

這是我的數據:

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

我想從_members刪除59527bd5e521801bf07eab98

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) 
    } 
); 
+0

當問問題,請包括這個問題本身,以及你所看到的任何錯誤消息。目前還不清楚什麼不適合你:是連接問題,是客戶端錯誤還是語法錯誤等? – Eye

+0

@Eye它可能已被更清楚地說明,但在這種情況下的「錯誤」是'.populate()'調用不應該做它應該和檢索相關數據。問題的關鍵在於什麼?修改標題以反映這一點 –

回答

1

有趣的是「P opulation「似乎只能通過在這種情況下將model選項指定爲.populate()而起作用。

此外,您只需要將member直接提供給$pull,因爲_id實際上不是屬性,直到「填充」爲止。 "_members"數組僅僅是Post本身內的ObjectId值的數組。所以,直接提供輸入:

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 
    } 
}) 

或者交替使用承諾:

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 

當您僅要求返回已嵌入文檔中的_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 
    } 
    ] 
} 
+0

非常感謝<3 – user1788781

+0

@ user1788781您可以使用您新獲得的[「upvote privileges」](https://stackoverflow.com/help/privileges) –