我正在尝试使用findOne()
查询这组数据:
{
"_id": {
"$oid": "5c1a4ba1482bf501ed20ae4b"
},
"wardrobe": {
"items": [
{
"type": "T-shirt",
"colour": "Gray",
"material": "Wool",
"brand": "Filson",
"_id": "5c1a4b7d482bf501ed20ae4a"
},
{
"type": "T-shirt",
"colour": "White",
"material": "Acrylic",
"brand": "H&M",
"_id": "5c1a4b7d482bf501ed20ae4a"
}
]
},
"tokens": [],
"email": "another@new.email",
"password": "$2a$10$quEXGjbEMX.3ERdjPabIIuMIKu3zngHDl26tgRcCiIDBItSnC5jda",
"createdAt": {
"$date": "2018-12-19T13:46:09.365Z"
},
"updatedAt": {
"$date": "2018-12-19T13:47:30.123Z"
},
"__v": 2
}
我想使用items
作为过滤器,从_Id
数组返回单个对象。这就是我的做法:
exports.deleteItem = (req, res, next) => {
User.findOne({ 'wardrobe.items': { $elemMatch: { "_id": "5c1a4b7d482bf501ed20ae4a",} } }, (err, item) => {
console.log(item);
if (err) {
return console.log("error: " + err);
}
res.redirect('/wardrobe');
});
};
但是,console.log(item)
会返回整个文档,就像这样:
{ wardrobe: { items: [ [Object], [Object] ] },
tokens: [],
_id: 5c1a4ba1482bf501ed20ae4b,
email: 'another@new.email',
password:
'$2a$10$quEXGjbEMX.3ERdjPabIIuMIKu3zngHDl26tgRcCiIDBItSnC5jda',
createdAt: 2018-12-19T13:46:09.365Z,
updatedAt: 2018-12-19T13:47:30.123Z,
__v: 2 }
我最终希望使用它来删除单个项目,因此我需要从子文档中过滤到单个对象。
答案 0 :(得分:1)
关于您的问题: MongoDB始终返回与查询匹配的完整对象,除非您添加一个投影以指定应返回的字段。 如果您确实只想返回嵌套对象,则可以将聚合管道与$ replaceRoot运算符一起使用,如下所示:
User.aggregate([
// you can directly query for array fields instead of $elemMatching them
{ $match: { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"}}},
// this "lifts" the fields wardrobe up and makes it the new root
{ $replaceRoot: {newRoot: '$wardrobe'}
// this "splits" the array into separate objects
{ $unwind: '$items'},
// this'll remove all unwanted elements
{ $match: { 'items._id': "5c1a4b7d482bf501ed20ae4a" },
},
])
这应该只返回想要的项目。
但是请注意:如果您仍然打算从数组中删除元素,我宁愿建议您看一下$ pull操作,该操作可以在满足特定条件的情况下从数组中删除元素:
https://docs.mongodb.com/manual/reference/operator/update/pull/
User.update(
{ 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"},
{ $pull: { 'wardrobe.items': {_id: "5c1a4b7d482bf501ed20ae4a"}},
{ multi: true }
)