这是我的数据:
{
"_id" : ObjectId("594e762b03cc52508686ceef"),
"_members" : [
"59527bd5e521801bf07eab98",
"594ecca47a699d1775c2a2db"
],
}
我想从
59527bd5e521801bf07eab98
中删除 _members
。PostSchema:
const PostsSchema = new Schema({
// ...
_members: [{ type: Schema.Types.ObjectId, ref: 'user' }],
// ...
})
用户架构:
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"
数组只是 ObjectId
本身内的 Post
值数组。所以直接提供输入:
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)
})
或与 promise
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
当您只要求返回已经嵌入文档中的
.populate()
字段时,有点不确定为什么要调用 _id
,但这是另一种情况。使用 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
}
]
}
关于javascript - 使用 findOneAndUpdate $pull 并填充不更新或填充,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44855998/