Reputation: 6820
So I have this code which save on the first attempt, however when the user visits another station I need it to add a new sub array under the history array.
NOTE: That if nothing is found (meaning UUID
I still need it to .save
).
const userData = {"UUID": query.uuid, "ipaddress":ip, "history":[{"HID":hid,"station":req.params.stationname, starttime: starttimestamp}]};
var listener = new Listeners(userData);
listener.save(function (err, book) {
if (err) return console.error(err);
console.log(book.UUID + " saved to collection.");
});
What is the correct way to do this?
I am getting the following error
{ MongoError: E11000 duplicate key error collection: AdStitchr.listeners index: UUID dup key: { UUID: "72296e08-2086-3b25-b66f-09fe14e7a1b9" }
at Connection.<anonymous> (/root/adstichrplayer/node_modules/mongodb/lib/core/connection/pool.js:466:61)
at emitTwo (events.js:126:13)
at Connection.emit (events.js:214:7)
at processMessage (/root/adstichrplayer/node_modules/mongodb/lib/core/connection/connection.js:384:10)
at TLSSocket.<anonymous> (/root/adstichrplayer/node_modules/mongodb/lib/core/connection/connection.js:553:15)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
at TLSWrap.onread (net.js:607:20)
operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1592964549 },
ok: 0,
errmsg: 'E11000 duplicate key error collection: AdStitchr.listeners index: UUID dup key: { UUID: "72296e08-2086-3b25-b66f-09fe14e7a1b9" }',
code: 11000,
codeName: 'DuplicateKey',
keyPattern: { UUID: 1 },
keyValue: { UUID: '72296e08-2086-3b25-b66f-09fe14e7a1b9' },
'$clusterTime':
{ clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1592964549 },
signature: { hash: [Object], keyId: [Object] } },
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {} }
when I use
const userData = {"UUID": query.uuid, "ipaddress":ip, "history":[{"HID":hid,"station":req.params.stationname, starttime: starttimestamp}]};
Listeners.findOneAndUpdate(
userData,
{ userData }, { upsert: true }, function(err) {
if (err) {
console.log('ERROR when submitting round');
console.log(err);
}
});
Upvotes: 2
Views: 34
Reputation: 1725
If you only have access to the variable userData
for some reason, and given that it has a valid object value of:
const userData = {"UUID": query.uuid, "ipaddress":ip, "history":[{"HID":hid,"station":req.params.stationname, starttime: starttimestamp}]}
you can do something like this:
Listeners.findOneAndUpdate(
{"UUID": userData.UUID, "ipaddress":userData.ipaddress },
{ $push: { history: userData.history[0] } },
{ upsert: true }, function(err) {
if (err) {
console.log('ERROR when submitting round');
console.log(err);
}
});
Upvotes: 1
Reputation: 49985
findOneAndUpdate
takes query as a first parameter. What you're doing is you're passing entire object as query including (most likely) non-deterministic starttimestamp
parameter. MongoDB will try to find such document with only one element in history
item and when there's no match the upsert: true
parameter will get applied and MongoDB will try to create a new document (since there's no match). Since you already have another document with such UUID
you're getting this error.
In order to fix that you need to pass UUID
and ipaddress
for the query part and then use $push to append you item to the history array:
Listeners.findOneAndUpdate(
{"UUID": query.uuid, "ipaddress":ip },
{ $push: { history: {"HID":hid,"station":req.params.stationname, starttime: starttimestamp} } },
{ upsert: true }, function(err) {
if (err) {
console.log('ERROR when submitting round');
console.log(err);
}
});
Upvotes: 1