findOne()返回整个文档,而不是单个对象

时间:2018-12-19 14:20:28

标签: node.js mongodb express mongoose

我正在尝试使用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 }

我最终希望使用它来删除单个项目,因此我需要从子文档中过滤到单个对象。

1 个答案:

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