When a user is created on my app their details are saved on the MongoDB using mongoose. The user schema
contains sub-documents and I am trying to access the _id
if the sub-document after using the user.save
function.
The schema is below:
{
name: String,
email: String,
address: String,
phone:[
{landLine: Number,
mobile: Number}
]
}
I can access the name, email and address easily like so:
console.log(user.name + user.email + user.address)
I tried user.phone._id
but it returns undefined
. I think because phone
is an array of objects.
user.save(function(err) {
if (err)
throw err;
else {
console.log("user ID " + user._id); // SUCCESS!!
console.log("user sub-document ID " + user.phone._id); // UNDEFINED!!
return (null, user);
}
});
How can I access the _id of the sub-document inside the save
function right after the user is created and saved into mongoDB?
There are a couple of approaches to getting this information, but personally I prefer the "atomic" modification method using$push
.
The actual implementation here is helped by mongoose automatically including an ObjectId
value which is "monotonic" and therefore always increasing in value. So this means that my method for handling this even works with a $sort
modifier applied to the$push
.
For example:
// Array of objects to add
var newNumbers = [
{ "landline": 55555555, "mobile": 999999999 },
{ "landline": 44455555, "mobile": 888888888 }
];
User.findOneAndUpdate(
{ "email": email },
{ "$push": { "phone": { "$each": newNumbers } } },
{ "new": true },
function(err,user) {
// The trick is to sort() on `_id` and just get the
// last added equal to the length of the input
var lastIds = user.phone.concat().sort(function(a,b) {
return a._id > b._id
}).slice(-newnumbers.length);
}
)
And even if you used a $sort
modifier:
User.findOneAndUpdate(
{ "email": email },
{ "$push": { "phone": { "$each": newNumbers, "$sort": { "landline": 1 } } } },
{ "new": true },
function(err,user) {
var lastIds = user.phone.concat().sort(function(a,b) {
return a._id > b._id
}).slice(-newnumbers.length);
}
)
That little trick of "sorting" a temporary copy on the _id
value means that the "newest" items are always at the end. And you just need to take as many off the end as you added in the update.
The arguable point here is that it's actually mongoose
that is inserting the _id
values in the first place. So in fact those are being submitted in the request made to the server for each array item.
You "could" get fancy and use "hooks" to record those ObjectId
values that were actually added to the new array members in the update statement. But it's really just a simple process of returning the last n
"greatest" _id
values from the array items anyway, so the more complex approach is not needed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.