Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
800 views
in Technique[技术] by (71.8m points)

javascript - Mongoose - Create document if not exists, otherwise, update- return document in either case

I'm looking for a way to refactor part of my code to be shorter and simpler, but I don't know Mongoose very well and I'm not sure how to proceed.

I am trying to check a collection for the existence of a document and, if it doesn't exist, create it. If it does exist, I need to update it. In either case I need to access the document's contents afterward.

What I've managed to do so far is query the collection for a specific document and, if it's not found, create a new document. If it is found, I update it (currently using dates as dummy data for this). From there I can access either the found document from my initial find operation or the newly saved document and this works, but there must be a better way to accomplish what I'm after.

Here's my working code, sans distracting extras.

var query = Model.find({
    /* query */
}).lean().limit(1);

// Find the document
query.exec(function(error, result) {
    if (error) { throw error; }
    // If the document doesn't exist
    if (!result.length) {
        // Create a new one
        var model = new Model(); //use the defaults in the schema
        model.save(function(error) {
            if (error) { throw error; }
            // do something with the document here
        });
    }
    // If the document does exist
    else {
        // Update it
        var query = { /* query */ },
            update = {},
            options = {};

        Model.update(query, update, options, function(error) {
            if (error) { throw error; }
            // do the same something with the document here
            // in this case, using result[0] from the topmost query
        });
    }
});

I've looked into findOneAndUpdate and other related methods but I'm not sure if they fit my use case or if I understand how to use them correctly. Can anyone point me in the right direction?

(Probably) Related questions:


Edit

I didn't come across the question pointed out to me in my searching, but after reviewing the answers there I've come up with this. It's certainly prettier, in my opinion, and it works, so unless I'm doing something horribly wrong I think my question can probably be closed.

I would appreciate any additional input on my solution.

// Setup stuff
var query = { /* query */ },
    update = { expire: new Date() },
    options = { upsert: true };

// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
    if (!error) {
        // If the document doesn't exist
        if (!result) {
            // Create it
            result = new Model();
        }
        // Save the document
        result.save(function(error) {
            if (!error) {
                // Do something with the document
            } else {
                throw error;
            }
        });
    }
});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are looking for the new option parameter. The new option returns the newly created document(if a new document is created). Use it like this:

var query = {},
    update = { expire: new Date() },
    options = { upsert: true, new: true, setDefaultsOnInsert: true };

// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
    if (error) return;

    // do something with the document
});

Since upsert creates a document if not finds a document, you don't need to create another one manually.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...