Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose is saving documents even if I check to see if the document already exists

I cam trying to check to see if an author is in mongo before I save the author. When I run my first rss document through the create author function, all of the authors are saved in the DB - even if they have authored two items in the feed.

What's strange is that if I run the feed through again, mongoose seems to be aware that the authors already exists and does not add them again. Can someone please explain to me what is happening?

function insertFeedItems(feedItems, newFeedID, callback) {
    feedItems.forEach((item) => {
        let firstName = item.author.substr(0, item.author.indexOf(' '));
        let lastName = item.author.substr(item.author.indexOf(' ') + 1);
        authorController.createAuthorInternally(firstName, lastName, function(author) {
            let aid = author.id;
            categoryController.createCategoryInternally(item.categories, function(categories) {
                // console.log('author: '+aid);
                // console.log('categories: '+categories);
            });
        });
    });

}


exports.createAuthorInternally = (firstName, lastName, callback) => {

    let author = authorFilter.validateAuthor(firstName, lastName);

    let queryParams = {
        $and: [{firstName: {$regex: firstName, $options: 'i'}},
            {lastName: {$regex: lastName, $options: 'i'}}],
    };

    let query = Author.findOne(queryParams).sort([['lastName', 'ascending']]);
    let findAuthor = query.exec();

    findAuthor.then((foundAuthor)=> {
        if (foundAuthor === null) {
            f1();
        }
    });

    function saveGuy() {
        return new Promise((resolve) => {
            let insertNewAuthor = author.save();
            resolve(insertNewAuthor);
        });
    }

    async function f1() {
        var name = await saveGuy();
    }
};

Edit: I've tried this a different way:

 Author.count(({'firstName': firstName}, { 'lastName': lastName }), function (err,count) {
        console.log(firstName + " " + lastName + " " + count);
                if(count === 0){
                    f1();
                }
    });

function saveGuy() {
    return new Promise((resolve) => {
        let insertNewAuthor = author.save();
        resolve(insertNewAuthor);
    });
}

async function f1() {
    var name = await saveGuy();
}

On the first run of this new method the output is:

Jon Brodkin 0
Peter Bright 0
Timothy B. Lee 0
Samuel Axon 0
Kyle Orland 0
Jon Brodkin 0
Kyle Orland 0
Megan Geuss 0
Cyrus Farivar 0
Peter Bright 0
Jim Resnick 0
Cyrus Farivar 0
Kyle Orland 0
Beth Mole 0
Ars Staff 0
Megan Geuss 0
Cyrus Farivar 0
John Timmer 0
Kyle Orland 0
Samuel Axon 0

On the second run with the same rss feed:

Cyrus Farivar 3
Jon Brodkin 2
Kyle Orland 4
Megan Geuss 2
Jon Brodkin 2
Ars Staff 1
Peter Bright 2
Jim Resnick 1
Peter Bright 2
Kyle Orland 4
Megan Geuss 2
Cyrus Farivar 3
Timothy B. Lee 1
Samuel Axon 2
Kyle Orland 4
Beth Mole 1
Cyrus Farivar 3
John Timmer 1
Kyle Orland 4
Samuel Axon 2

As of offering the bounty, this is the method that I'm using to find and save:

exports.createAuthorInternally = (firstName, lastName, callback) => {

   let query = Author.findOne({firstName: firstName,lastName: lastName});

    query.exec(function(err,doc) {
        if(err){console.log(err)}
        if(!doc){
            let auth = new Author({firstName: firstName, lastName: lastName});
            auth.save(auth, function(err,newdoc) {
                if(err){console.log(err)}
                callback(newdoc);
            });
        }else{
            callback(doc);
        }

    });

The results are the same as in the previous methods.

Edit: JohnnyHK pointed out my error. I've adjusted the code to reflect his answer:

function insertFeedItems(feedItems,newFeedID){

    async.eachSeries(feedItems, function(item, eachCallBack) {

        let firstName = item.author.substr(0, item.author.indexOf(' '));
        let lastName = item.author.substr(item.author.indexOf(' ') + 1);
        async.waterfall([
                (callback) => {
                    authorController.createAuthorInternally(firstName, lastName, function(author) {
                        return callback(null, author, item.categories);
                    });
                },
                (author, categories, callback) => {
                    categoryController.createCategoryInternally(categories, function(categories) {
                        return callback(null, author, categories);
                    });
                },
                (author, categories, callback) => {
                    feedEntryController.createFeedEntry(item, author, categories, function(entry) {
                        return callback(null, author, categories, entry);
                    });
                },
            ],
            function(waterfallError) {
                if(!waterfallError){
                    eachCallBack();
                }
            });
    }, function(eachSeriesErr) {
        if(eachSeriesErr) {
            console.log('An item failed to process');
        } else {
            console.log('All items have been processed successfully');
        }
    });
}
like image 752
user465001 Avatar asked Apr 03 '18 21:04

user465001


1 Answers

JohnnyHK pointed out my error. Using the library, Async - I've adjusted the code to reflect his answer:

function insertFeedItems(feedItems,newFeedID){

async.eachSeries(feedItems, function(item, eachCallBack) {

    let firstName = item.author.substr(0, item.author.indexOf(' '));
    let lastName = item.author.substr(item.author.indexOf(' ') + 1);
    async.waterfall([
            (callback) => {
                authorController.createAuthorInternally(firstName, lastName, function(author) {
                    return callback(null, author, item.categories);
                });
            },
            (author, categories, callback) => {
                categoryController.createCategoryInternally(categories, function(categories) {
                    return callback(null, author, categories);
                });
            },
            (author, categories, callback) => {
                feedEntryController.createFeedEntry(item, author, categories, function(entry) {
                    return callback(null, author, categories, entry);
                });
            },
        ],
        function(waterfallError) {
            if(!waterfallError){
                eachCallBack();
            }
        });
}, function(eachSeriesErr) {
    if(eachSeriesErr) {
        console.log('An item failed to process');
    } else {
        console.log('All items have been processed successfully');
    }
});
}
like image 175
user465001 Avatar answered Sep 28 '22 13:09

user465001