1

I have a [user] document stored that contains a nested sub-array [profiles],[favorites]. I am simply trying to delete($pull) a favorites from a given profile based on the favorites name.

{
"_id" : ObjectId("558d53eebdd9804820090fa1"),    
"name" : "Frank",
"email" : "[email protected]",   
"profiles" : [ 
    {
        "avatar" : "div-male",
        "age" : "35",
        "gender" : "Male",
        "profilename" : "Oly Lifter",
        "_id" : ObjectId("558d5404bdd9804820090fa2"),
        "favorites" : [ 
            {
                "name" : "Power Clean"
            }, 
            {
                "name" : "Hang Clean"
            }, 
            {
                "name" : "Clean and Jerk"
            }
        ],
        "createdAt" : ISODate("2015-06-26T13:30:44.661Z")
    }
    ],
    "createdAt" : ISODate("2015-06-26T13:30:22.884Z"),
    "role" : "user",
    "__v" : 0
}

Using a MongoDB IDE robomongo, I'm able to successfully remove a favorite item from a known User and Profile ID using this

 db.users.update($find: {
        'profiles': {
            'profiles._id': ObjectId("558d5404bdd9804820090fa2")
        },
        {
            $pull: {
                'profiles.$.favorites': {
                    'name': 'Hang Clean'
                }
            }
        })

However, when I call from my server API using the following syntax, I receive an error, note req.body._id = "558d5404bdd9804820090fa2" and req.body.favorites.name = "Hang Clean"

User.findByIdAndUpdate(_user._id, {
    'profiles._id': req.body._id
    }, {
    $pull: {
        'profiles.$.favorites': {
            'name': req.body.favorites.name
        }
    }
    }, {
    safe: true,
    upsert: true
    },
    function(err, model) {
    if (err) {
        console.log(err);
        return res.status(500).send('Error Deleting Profile');
    }
    return res.status(200).send('Profile Deleted!');
    });
3
  • { [MongoError: exception: The positional operator did not find the match needed from the query. Unexpanded update: profiles.$.favorites] name: 'MongoError', errmsg: 'exception: The positional operator did not find the match needed from the query. Unexpanded update: profiles.$.favorites', code: 16836, ok: 0 } Commented Jun 26, 2015 at 14:36
  • Can you update your question with the exact schema, it seems rather unclear what the actual document is as you have a top level user key on the document? Commented Jun 26, 2015 at 14:41
  • Done, that's exactly how it reads in robomongo's document editor. Commented Jun 26, 2015 at 14:52

1 Answer 1

1

Try updating using the findOneAndUpdate() method since you are supplying the findByIdAndUpdate() method with the wrong parameters: the second argument { 'profiles._id': req.body._id } should be part of the first query object hence you need to use the findOneAndUpdate() method as follows, making sure you convert the string ids into ObjectId's:

var mongoose = require('mongoose');
var id = mongoose.Types.ObjectId(_user._id),
    profileId = mongoose.Types.ObjectId(req.body._id),
    query = {
        "_id": id,
        "profiles._id": profileId 
    },
    update = {
        "$pull": { 
            "profiles.$.favorites": { "name": req.body.favorites.name }
        }
    },
    options = { "multi": true, "upsert": true };

User.findOneAndUpdate(query, update, options, function(err, model) {
     if(err){
        console.log(err);
        return res.status(500).send('Error Deleting Profile');
     }
     return res.status(200).send('Profile Deleted!');       
}); 
Sign up to request clarification or add additional context in comments.

2 Comments

This worked perfectly! Also like the argument structure, much more readable.
@CampbellGolf No worries!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.