Mongo/Mongoose check if an item exists

10,691

If you were looking for one item in the tracksTable collection you could do something like this:

tracksTable.findOne({for_user: req.user._id}, function(err, tracksTableItem) {
    if (err) {
        console.log("MongoDB Error: " + err);
        return false; // or callback
    }
    if (!tracksTableItem) {
        console.log("No item found, creating tracksTable item");

        tracksTable.create(
            {
                for_user: req.user._id,
                title: req.body[i].title,
                artist: req.body[i].artist,
                artwork: req.body[i].artwork,
                source: req.body[i].source,
                stream: req.body[i].stream
            }, function(err, createdItem) {
                if (err) {
                    console.log("MongoDB Error: " + err);
                    return null; // or callback
                }
            }
        );
    }
    else {
        console.log("Found one tracksTable item: " + tracksTableItem.for_user);
        // here you could even update your existing item using "tracksTable.save"
    }
    return true; // or callback
}
Share:
10,691
leaksterrr
Author by

leaksterrr

Front-End Web Geek.

Updated on June 04, 2022

Comments

  • leaksterrr
    leaksterrr almost 2 years

    I'm pretty new to building large-scale web applications with Mongo and Mongoose and I'm wondering what the correct way to check if an items exists is.

    I've commented the function below so it should be easy to understand what I'm doing and the wall I've hit. So essentially what I'm creating is: item_exists ? do nothing : save. I've currently removed the 'save' function as I'm not too sure where it should be placed.

    app.post('/tracks/add/new', function (req, res) {
    
            var newTrack;
    
            // loop through the objects in req.body
            // item_exists ? do nothing : save
    
            for (var i = 0; i < req.body.length; i++) {
    
                newTrack = new tracksTable({
                    for_user: req.user._id,
                    title: req.body[i].title,
                    artist: req.body[i].artist,
                    artwork: req.body[i].artwork,
                    source: req.body[i].source,
                    stream: req.body[i].stream
                });
    
                // check if the item already exists by
                // first finding the 'for_user' field and
                // any tracks associated with it (title)
    
                var query = tracksTable.find({});
    
                query
                    .where('for_user', req.user._id)
                    .select('title')
                    .exec(function (err, data) {
                        for (var x = 0; x < data.length; x++) {
    
                            // this is where I've hit a wall...
                            // does 'this' track in the database match
                            // one in the request?
    
                        }
                    });
    
            }
    
        });
    
  • leaksterrr
    leaksterrr over 9 years
    for_user is my relational field and one that I'm also using as a unique identifier for the lookups. I need to look for a 'for_user' item and see if it has a 'title' that matches one in the request. If not then save it to the tracks db.
  • Santiag00
    Santiag00 over 9 years
    I guess you could either add the req.body[i].title to the findOne condition or loop through the "tracksTableItem" tracks if a track item was found using the "for_user" field
  • leaksterrr
    leaksterrr over 9 years
    It's going to have to be the latter because the track could exist for another user but I'm doing two pretty big loops now (req loop and db loop)... Surely there's got to be a cleaner way?
  • Santiag00
    Santiag00 over 9 years
    Hmm unless I'm missing something and assuming the title is a simple String field I don't see why you can't do "findOne({for_user: req.user._id, title: req.body[i].title})" to look just for those tracks that belong to a certain user and have a certain title.