RussellHarrower
RussellHarrower

Reputation: 6820

Note inserting new sub array

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

Answers (2)

Karl L
Karl L

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

mickl
mickl

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

Related Questions