Hello,
I have the following code:
mongooseInstance.array.addToSet({user: uid, name: "theName"});
mongooseInstance.save(function(err,mongooseInstance){
if(err){
//DO something
} else {
//do something else with mongooseInstance
}
});
Knowing that the mongooseInstance.array already contain the object {user: uid, name: "theName"}.
There isnt duplicate entries in the db but my mongooseInstance after the save contain two object {user: uid, name: "theName"}.
mongooseInstance.array = [{user: uid, name: "theName"},{user: uid, name: "theName"}]
I can get what i want by querying the mongooseInstance again but it doesnt seems really effective.
Can you clarify? I don't quite understand your issue.
Ok i will try to clarify my problem hopping im not wasting your time.
mongooseInstance.objectArray = [];
mongooseInstance.objectArray.addToSet({user: objectId("anObjectId"), name: "aSimpleName"});
mongooseInstance.save();
//console.log(mongooseInstance.objectArray) => [{user: objectId("anObjectId"), name: "aSimpleName"}]
//Everything is fine !
//Now if i add the same object to my objectArray:
mongooseInstance.objectArray.addToSet({user: objectId("anObjectId"), name: "aSimpleName"});
mongooseInstance.save();
console.log(mongooseInstance.objectArray) => [{user: objectId("anObjectId"), name: "aSimpleName"} , {user: objectId("anObjectId"), name: "aSimpleName"}]
//Here i have the duplicate object in my objectArray, then if i query the instance back from the db:
var freshInstance = MongooseModel.find(mongooseInstance.id);
console.log(freshInstance.objectArray) => [{user: objectId("anObjectId"), name: "aSimpleName"}]
I dont understand why after the second addSet, i get a duplicate object in my objectArray even if in the db it wont be saved.
The below script works as expected for me:
'use strict';
var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/gh4128');
mongoose.set('debug', true);
var schema = new Schema({
objectArray: [{ name: String }]
});
var Model = mongoose.model('Test', schema);
Model.create({}, function(error, m) {
assert.ifError(error);
var id = new mongoose.Types.ObjectId();
m.objectArray.addToSet({ _id: id, name: 'val' });
console.log(m);
m.save(function(error) {
assert.ifError(error);
m.objectArray.addToSet({ _id: id.toString(), name: 'val' });
console.log(m);
process.exit(0);
});
});
output:
$ node gh-4128.js
Mongoose: tests.insert({ _id: ObjectId("5730a8bd0dd65094198bbf0e"), objectArray: [], __v: 0 })
{ objectArray: [ { name: 'val', _id: 5730a8bd0dd65094198bbf0f } ],
_id: 5730a8bd0dd65094198bbf0e,
__v: 0 }
Mongoose: tests.update({ _id: ObjectId("5730a8bd0dd65094198bbf0e") }) { '$addToSet': { objectArray: { '$each': [ { _id: ObjectId("5730a8bd0dd65094198bbf0f"), name: 'val' } ] } }, '$inc': { __v: 1 } }
{ objectArray: [ { name: 'val', _id: 5730a8bd0dd65094198bbf0f } ],
_id: 5730a8bd0dd65094198bbf0e,
__v: 1 }
Can you see if you can modify the above script to repro your issue? Also, can you clarify which version of mongoose?
Hi,
sorry for the delay.
Im using mongoose 4.4.13.
I do agree, your piece of code works as expected.
However in my use case i dont have an id also my Schema is not the same:
'use strict';
var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/gh4128');
mongoose.set('debug', true);
var schema = new Schema({
objectArray: []
});
var Model = mongoose.model('Test', schema);
Model.create({}, function(error, m) {
assert.ifError(error);
m.objectArray.addToSet({name: 'val' });
console.log(m);
m.save(function(error) {
assert.ifError(error);
m.objectArray.addToSet({name: 'val' });
m.objectArray.addToSet({name: 'val' });
console.log(m);
m.save(function(error){
console.log(m);
process.exit(0);
});
});
});
output:
Mongoose: tests.insert({ _id: ObjectId("573340ccb9808f8879cb05ad"), objectArray: [], __v: 0 })
{ objectArray: [ { name: 'val' } ],
_id: 573340ccb9808f8879cb05ad,
__v: 0 }
Mongoose: tests.update({ _id: ObjectId("573340ccb9808f8879cb05ad") }) { '$addToSet': { objectArray: { '$each': [ { name: 'val' } ] } }, '$inc': { __v: 1 } }
{ objectArray: [ { name: 'val' }, { name: 'val' }, { name: 'val' } ],
_id: 573340ccb9808f8879cb05ad,
__v: 1 }
{ objectArray: [ { name: 'val' }, { name: 'val' }, { name: 'val' } ],
_id: 573340ccb9808f8879cb05ad,
__v: 2 }
Mongoose: tests.update({ _id: ObjectId("573340ccb9808f8879cb05ad") }) { '$addToSet': { objectArray: { '$each': [ { name: 'val' }, { name: 'val' } ] } }, '$inc': { __v: 1 } }
If you look in the db, you'll se that there is just one item in objectArray.
This is what i want in fact, but if you look the last objectArray log, you can see that the array contains 3 val and that's the thing i dont understand.
Wow!
So that's possible to update document by calling array update operators right from instance!
It's not documented at mongoose website at all. Where I can read about this?
How can I do this
post.contributors.addToSet({
$each: _.map(users, function(item){ return item._id }) // guessed, wrong syntax, not working
}, cb);
instead of this?
Post.update({post: post.title}, {
$addToSet: { // working
contributors: {
$each: _.map(users, function(item){ return item._id })
}
}
}, cb);
Where contributors is array of Objectids from other collection.
Not sure how well documented it is but you can do doc.array.addToSet() followed by doc.save() and that does a $addToSet under the hood
@vkarpov15 what about $each helper?
Exactly this part wasn't obvious for me
Call addToSet multiple times. In your example in an _.each
Most helpful comment
Not sure how well documented it is but you can do doc.array.addToSet() followed by doc.save() and that does a $addToSet under the hood