How to create it if it doesn't exist or update it if it does exist?

Hi community.
I’m developing a Notification system. I have basically a User schema containing an array of references to Notification messages.

The server sends to my API endpoint an big list of Users and the message to notify them.
I want to add the Message ID to each User’s array if the user exists, or create it if the user doesn’t exist.

Since I am a new comer to the NoSQL world, it is taking me time to realize the best way of doing it and not fall into a Big O^N problem.

The User collection is expected to have more than 100K entries.
Right now my algorithm is as follows:
New broadcast notification arrives
I query mongo to check if the user exists.
If it does, I update the array
If it doesn’t I create the new User and add the notification to its array.
Problem: The more users I add to the db, the longer it takes to query for existing users.
That is the Big O^N problem.

 for(let i=0; i<users.length; i++){
   let usr = await User.findOneAndUpdate({usuarioID: users[i].usuarioID}, {$push: {broadcast_message: {id: idNotificacion._id, seen: false}}} )

   if(usr === null ){
      
      users[i].broadcast_message = [{id: idNotificacion._id, seen: false}]
      const usuarioID = await User.create(users[i]);
    }
 }
}

Is there any smart or clever solution? I am not really proficient at NoSQL yet.

This is the short version of the schema:

const UserSchema = new mongoose.Schema({
	_id,
    message_broadcast: [{ 
        id: {
            type:  mongoose.Schema.Types.ObjectId ,
            ref: 'BroadcastNotification', //another collection, containing only Notification Messages.
            required: true
            },
       }
    ]}
}

Is there an index on the collection on field usuarioID? And take a look at upserts which I believe should do the kind of thing you want.

Thats it!
The index was by default on _id, but I was using userID for my search.
I just added an index on userID and that was it.
Just inserted over 70K documents in 17 seconds, and 30K in less than 10 seconds. More than enough to move forward.

Thanks again John!

const bulkOperations = usuarios.map( (usuario : any) => {
  return {
    updateOne: {
      filter: { usuarioID: usuario.usuarioID },
      update: { $push: {mensajes_broadcast: idNotificacion } },
      upsert: true
    }
  };
});
  await Usuario.bulkWrite(bulkOperations)
}

You could also look at doing an upsert in a bulk update…

I just saw you are…my reading skills failed there!

You could have a look at the bulk options though, if your updates don’t HAVE to be in order you could set the options for this…which could improve performance.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.