【问题标题】:Using pull in mongoose model使用拉入猫鼬模型
【发布时间】:2015-06-12 19:10:26
【问题描述】:

这应该有效吗?我正在尝试从 UserSchema 模型中的文档 (this) 中删除单个子文档 (following)。

UserSchema.methods.unFollow = function( id ) {
var user = this

return Q.Promise( function ( resolve, reject, notify ) {
    var unFollow = user.following.pull( { 'user': id } )

    console.log( unFollow )

    user.save( function ( error, result ) {
        resolve( result )   
    })  
})
}

这些是架构:

var Follows = new mongoose.Schema({
    user: String,
    added: Number
})

var UserSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    following: [ Follows ]
})

用户控制器.js

/*
Unfollow user.
*/
exports.unFollow = function ( req, res ) {

    User.findOne( { token: req.token }, function ( error, user ) {
        user.unfollow( req.body.id )
        .onResolve( function ( err, result ) {
            if ( err || !result ) return res.status( 500 ).json( "User could not be unfollowed." )

            return res.status( 200 ).json( "User unfollowed." )
        })
    })
}

用户模型.js

/*
Unfollow a user.
*/
UserSchema.method( 'unfollow', function unfollow ( id ) {
    this.following.pull( { user: id } )

    return this.save()
})

【问题讨论】:

    标签: node.js mongodb mongoose subdocument


    【解决方案1】:

    您通常使用method 函数分配方法:

    UserSchema.method('unFollow', function unFollow(id) {
      var user = this;
    
      user.following.pull({_id: id});
      // Returns a promise in Mongoose 4.X
      return user.save();
    });
    

    另外,如上所述,您不需要使用 Q,因为 save 将返回 mongoose promise

    更新:Mongoose 的数组 pull 方法将适用于匹配的原始值,但对于子文档对象,它只会匹配 _id

    更新#2:我刚刚注意到您更新的问题表明您的控制器首先进行查找,修改返回的文档,然后将文档保存回服务器。为什么不创建一个静态而不是一个方法来做你想做的事?这有一个额外的好处是对数据库的一次调用而不是每个操作两次。

    例子:

    UserSchema.static('unfollow', function unfollow(token, id, cb) {
      var User = this;
    
      // Returns a promise in Mongoose 4.X
      // or call cb if provided
      return User.findOneAndUpdate({token: token}, {$pull: {follows: {user: id}}}, {new: true}).exec(cb);
    });
    
    User.unfollow(req.token, req.body.id).onResolve(function (err, result) {
      if (err || !result) { return res.status(500).json({msg: 'User could not be unfollowed.'}); }
    
      return res.status(200).json({msg: 'User unfollowed.'})
    });
    

    奖金follow静态:

    UserSchema.static('follow', function follow(token, id, cb) {
      var User = this;
    
      // Returns a promise in Mongoose 4.X
      // or call cb if provided
      return User.findOneAndUpdate({token: token}, {$push: {follows: {user: id}}}, {new: true}).exec(cb);
    });
    
    User.follow(req.token, req.body.id).onResolve(function (err, result) {
      if (err || !result) { return res.status(500).json({msg: 'User could not be followed.'}); }
    
      return res.status(200).json({msg: 'User followed.'})
    });
    

    【讨论】:

    • 谢谢,但这仍然不会删除user 字段为id 的子文档。它似乎返回了受影响的对象,就像它在拉动之前一样。但是子文档的问题仍然存在。
    • 您使用的是哪个版本的猫鼬?这适用于带有 user.unfollow(userToUnfollow).onResolve(function (err, user) {...}) 的猫鼬 4.0.1
    • 我正在使用4.0.1(刚刚升级)。我在上面添加了我的控制器代码。
    • 也试过this.update( { $pull: { following: { user: id } } } ) 似乎执行没有错误,但没有任何内容被删除。
    • 道歉。我使用了不同的架构,其中following 子文档只是user。 Mongoose 的 pull 仅匹配 _id,因此您需要将其传入并匹配。
    【解决方案2】:

    注意:用于"mongoose": "^5.12.13"

    至于今天 2021 年 6 月 22 日,您可以使用 $in$pull mongodb 运算符从文档数组中删除项目:

    父文档:

    {
        "name": "June Grocery",
        "description": "Some description",
        "createdDate": "2021-06-09T20:17:29.029Z",
        "_id": "60c5f64f0041190ad312b419",
        "items": [],
        "budget": 1500,
        "owner": "60a97ea7c4d629866c1d99d1",
    }
    

    Items 数组中的文档:

            {
                "category": "Fruits",
                "bought": false,
                "id": "60ada26be8bdbf195887acc1",
                "name": "Kiwi",
                "price": 0,
                "quantity": 1
            },
            {
                "category": "Toiletry",
                "bought": false,
                "id": "60b92dd67ae0934c8dfce126",
                "name": "Toilet Paper",
                "price": 0,
                "quantity": 1
            },
            {
                "category": "Toiletry",
                "bought": false,
                "id": "60b92fe97ae0934c8dfce127",
                "name": "Toothpaste",
                "price": 0,
                "quantity": 1
            },
            {
                "category": "Toiletry",
                "bought": false,
                "id": "60b92ffb7ae0934c8dfce128",
                "name": "Mouthwash",
                "price": 0,
                "quantity": 1
            },
            {
                "category": "Toiletry",
                "bought": false,
                "id": "60b931fa7ae0934c8dfce12d",
                "name": "Body Soap",
                "price": 0,
                "quantity": 1
            },
            {
                "category": "Fruit",
                "bought": false,
                "id": "60b9300c7ae0934c8dfce129",
                "name": "Banana",
                "price": 0,
                "quantity": 1
            },
            {
                "category": "Vegetable",
                "bought": false,
                "id": "60b930347ae0934c8dfce12a",
                "name": "Sombe",
                "price": 0,
                "quantity": 1
            },
    

    查询:

    MyModel.updateMany(
        { _id: yourDocumentId },
        { $pull: { items: { id: { $in: itemIds } } } },
        { multi: true }
      );
    

    注意:ItemIds 是一个ObjectId 数组。见下文:

    [
      '60ada26be8bdbf195887acc1',
      '60b930347ae0934c8dfce12a',
      '60b9300c7ae0934c8dfce129'
    ] 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 2017-10-05
      • 2019-08-04
      • 2018-03-04
      • 2018-07-15
      • 2014-12-09
      • 2018-12-23
      相关资源
      最近更新 更多