How to prevent duplicate documents mongodb with mongoose

Viewed 2214

I have a user collection and a portfolio collection on mongodb. The portfolio model references the objectid of the users collection. I'm trying to make it so when a user is logged in, and they try to add document they already have, the router prevents it. Right now all this does is look through all the documents in the portfolio collection but I'm trying to filter it by users first, then search the name to see if it's there.

  portfolio.find({name: req.body.name})
  .count()
  .then(count => {
    if (count > 0) {
      // There is an existing user with the same username
      res.status(400).json({message: 'Stock already saved!'});
    }else{
     portfolio
     .create({
       user: req.body.user,
       name: req.body.name,
       description: req.body.description,
       symbol: req.body.symbol,
       image: req.body.image,
     })
     .then(portfolioPost => res.status(201).json(portfolioPost.serialize()))
     .catch(err => {
       // console.error(err);
       res.status(500).json({ error: 'Something went wrong' });
     });
    }
  })

this is the model

const listSchema = mongoose.Schema({
  user: { type: mongoose.Schema.Types.ObjectId, ref: "Users" },
  name: { type: String, required: true },
  description: {type:String, required: true},
  image: {type:String},
  symbol: {type: String, required: true}
});
1 Answers

Use { unique: true } So, whenever anyone tries to use same user id to multiple portfolios, the mongoose will throw an error.

Your model will be then,

const listSchema = mongoose.Schema({
  user: { type: mongoose.Schema.Types.ObjectId, ref: "Users", unique: true },
  name: { type: String, required: true },
  description: {type:String, required: true},
  image: {type:String},
  symbol: {type: String, required: true}
});

I used the user properties unique. So no two list schema can have the same userId.

Finally, you can skip finding previous user portfolio. Your code can be

portfolio
     .create({
       user: req.body.user,
       name: req.body.name,
       description: req.body.description,
       symbol: req.body.symbol,
       image: req.body.image,
     })
     .then(portfolioPost => res.status(201).json(portfolioPost.serialize()))
     .catch(err => {
       // console.error(err);
       res.status(500).json({ error: 'Something went wrong' });
     });

In this case, if there already a portfolio with the current userId, the MongoDB will be sent an error.

For more details, please check the Additional Options section.

Related