Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose update not persisting

Using mongodb and mongoose, I can not get the $push to append an element to my array. After I run this, I check in the mongo shell and the new append is not there. Not sure what I am doing wrong:

UserModel.findOne({ firstName: "bob" }, 'pets', function(err, user) {
  UserModel.update(user, {
    $push: {
      pets: {
          name: "pear", type: "pig"  
      }
    }
  }, function(err, numAffected, raw) {
      if (err) console.log(err);
      console.log('updated ' + JSON.stringify(numAffected));
  });
});

Mongoose: users.ensureIndex({ username: 1 }) { unique: true, background: true }  
Mongoose: users.findOne({ firstName: 'bob' }) { fields: { pets: 1 } }  
Mongoose: users.update({ pets: [ { type: 'dog', name: 'apple' }, { type: 'cat', name: 'felix' } ], _id: ObjectId("56a53d45a428cbde3c4299f8") }) { '$push': { pets: { name: 'pear', type: 'pig' } } } {} 
updated {"ok":1,"nModified":0,"n":0}

> bob = db.users.find()[0]
{
    "_id" : ObjectId("56a53d45a428cbde3c4299f8"),
    "firstName" : "bob",
    "lastName" : "smith",
    "username" : "bob123",
    "pets" : [
        {
            "name" : "apple",
            "type" : "dog"
        },
        {
            "name" : "felix",
            "type" : "cat"
        }
    ],
    "__v" : 0
}
> 

UPDATE: After changing the type field, still not having success. This time I am just trying to push { $push: { pets: "sssss" } }.

UserModel.findOne({ firstName: "bob" }, 'pets', function(err, user) {
  UserModel.update(user,
    { $push: { pets: "sssss" }},
    function(err, numAffected, raw) {
      if (err) console.log(err);
      console.log('updated ' + JSON.stringify(numAffected));
  });
});

Here is the actual mongodb log:

2016-01-29T03:14:37.030+0000 I COMMAND  [conn17] command curves.$cmd command: update { update: "users", updates: [ { q: { pets: [ { petType: "pig", name: "pear" } ], _id: ObjectId('56aad0a3ef5848c231ec80ed') }, u: { $push: { pets: "sssss" } }, upsert: false, multi: false } ], ordered: true, writeConcern: { w: 1 } } ntoskip:0 keyUpdates:0 writeConflicts:0 numYields:0 reslen:55 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, Database: { acquireCount: { w: 1 } }, Collection: { acquireCount: { w: 1 } } } protocol:op_query 0ms
like image 368
dman Avatar asked Jan 24 '16 22:01

dman


2 Answers

Here. This is is similar code and it is working. findbyidandupdate needs to have a "new : true" optional param added to it. Otherwise you will get the old doc returned to you.

var express = require("express");
var app = express();
var mongoose = require("mongoose");

mongoose.connect("mongodb://localhost/population");

var db = mongoose.connection;

db.on("error", console.error.bind(console, "connection error:"));
db.once("open", function(){
    var mongoose = require("mongoose");

    var userSchema = new mongoose.Schema({
        firstname : String,
        lastname : String,
        pets : []
    })
    var userModel = mongoose.model("User", userSchema);

    var bob = new userModel({
        "firstname" :"bob",
        "lastname" : "Smith",
        "pets" : [
            {name : "apple", type : "dog"},
            {name : "felix", type : "cat"}
        ]
    })

    bob.save(bob, function(err, user){
        console.log(user)
    });

  userModel.findOneAndUpdate(
        {firstname : "bob"}, 
        {$push : {"pets" : {name : "pear", type : "pig"}}},
         //THE MOST IMPORTANT PART ADD new : true
        {safe : true, upsert : true, new : true},
        function(err, model){
            console.log(model);
        }
  )

})//once


app.listen(3000, function(){
    console.log("listening on port: " , 3000)
})
like image 144
jack blank Avatar answered Nov 14 '22 20:11

jack blank


The real reason is that the type used in the pets array is not correctly. Actually, type is one keyword of mongoose, which is used to mark the Schema Type.

If change the type to type1 as following schema

var UserSchema = new mongoose.Schema({
    // ....
    pets: [{name: String, type1: String}],
});

The saved pets should as following with extra _id

"pets" : [
    {
        "name" : "o3",
        "type1" : "t3",
        "_id" : ObjectId("56a5df9adea3071b0de83407")
    },

Under this case, we can do the following

UserModel.findOne({ firstName: "bob" }, 'pets', function(err, user) {
  UserModel.update(user, {
    $push: {
      pets: {
          name: "pear", type1: "pig"  
      }
    }
  }, function(err, numAffected, raw) {

And the result is

"pets" : [
    {
        "name" : "o3",
        "type1" : "t3",
        "_id" : ObjectId("56a5df9adea3071b0de83407")
    },
    {
        "type1" : "pig",
        "name" : "pear",
        "_id" : ObjectId("56a5dff3a648301d0db118df")
    }
],
like image 2
zangw Avatar answered Nov 14 '22 18:11

zangw