Adam Weiler
Adam Weiler

Reputation: 571

Prevent Duplicate Documents in MongoDB?

I'm trying to figure out the best way to prevent duplicate documents from being saved in MongoDB.

Right now my form takes the user_url from the user. The logic is:

I think my 2 options are:

var findOneURL = function(user_url, done) {
    URL.findOne({
        orig_url: user_url
    }, (err, data) => {
        if (err) {
            done(err);
        }
        done(null, data);
    })
}

or

var findEditThenSave = function(user_url, done) {
    URL.findById(user_url, (err, data) => {
        if (err) {
            done(err);
        }

        data.save((err, data) => {
            if (err) {
                done(err);
            }
            done(null, data);
        });
    })
};

It's not working terribly well at the moment but this is the live version: https://kindly-fisherman.glitch.me/

EDIT2: I think I got it working properly now. Here's my logic:

Saving to database: dns.lookup -> findByURL -> (If it doesn't exist) -> countURLs -> findAndUpdateURL -> Return what was saved to database.

OR -> (If it exists) -> Return the record.

Retrieving from database: findByID

Upvotes: 3

Views: 6451

Answers (2)

Govi-Boy
Govi-Boy

Reputation: 99

Instead of using

 db.insert() 

you should use

db.update() 

and specify

$upsert: true

[here]

Upvotes: 0

styopdev
styopdev

Reputation: 2664

The best choice is findOneAndUpdate query with upsert and returnNewDocument options

db.collection.findOneAndUpdate({ orig_url: user_url }, { $set: { orig_url: user_url }}, { upsert: true, returnNewDocument: true })

In mongoose

URL.findOneAndUpdate({orig_url: user_url }, { $set: { orig_url: user_url }}, { upsert: true, new: true }, (err, data) => {
    if (err) {
        done(err);
    }
    // data will contain your document
    done(null, data);
});

upsert option specifies whether to insert document if not found, new (returnNewDocument in mongo's console) - whether to return old or updated document - if false (default is false) you will have null for inserted documents.

Upvotes: 4

Related Questions