Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
464 views
in Technique[技术] by (71.8m points)

node.js - Mongoose update 'cannot use the part (..) to traverse the element

I have this really annoying issue where i can't update anything using mongoose. It's really frustrating to use, and the documentation is not helping at all.

I have this schema:

var userSchema = mongoose.Schema({

    local            : {
        email        : String,
        password     : String,
    },
    devices : [{
      id : String,
      name : String
    }]
});

And this is the code where i want to add a device to the array devices :

function updateDeviceList(user, deviceID, deviceName)
{
  User.update({ 'local.email' : user}, 
  { $set: {'devices.id' : deviceID, 'devices.name' : deviceName}}, 
  function(err, response)
  {
    if(err)
    {
      console.log("Update device error", err);
    }
    else {
      console.log("Update device OK");
    }
  });
}

At this point i get the error: errmsg: 'cannot use the part (devices of devices.id) to traverse the element ({devices: []})' }

I didn't manage to find an explanation to why this is happening. I have to mention that the document (there is pretty much only one document in the database), is this one:

{
    "_id": {
        "$oid": "5585a196fe11b21100635c74"
    },
    "devices": [],
    "local": {
        "password": "$2a$10$7hXVHw7izcYlqbD6xe/te.0w2zucZ7lA007g9kXdoIMPhZhRyCIru",
        "email": "[email protected]"
    },
    "__v": 0
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try to use the positional $ operator in the update which identifies an element in an array to update without explicitly specifying the position of the element in the array, but this will only ever match one element at a time:

 User.update(
    { 
        "local.email": user,
        "devices.id": { "$ne": deviceID },
        "devices.name": { "$ne": deviceName }
    }, 
    { 
        "$set": { 
            "devices.$.id": deviceID,
            "devices.$.name": deviceName 
        }
    } 
);

From the docs, the positional $ operator acts as a placeholder for the first element that matches the query document, and the array field must appear as part of the query document hence the query document

"devices.id": { "$ne": deviceID },
"devices.name": { "$ne": deviceName }

contains the device array and will match those documents where the device array id is not equal to deviceID and the name is not the same as the name which you are trying to update. This will even match documents where the device array is empty.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...