HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

'join' MongodDB collections with a for loop

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withloopjoinforcollectionsmongoddb

Problem

This is a very simplified version of my query. Is it acceptable to join the two collections for the client with the use of for loops?

There could be up to 2,000 books, which also means there could be an equal number of favorite books per user in the favoriteBooksCollection.

return favoriteBooksCollection
.find({user: current_userId})
.then(function(favorites){

    var bookIds = favorites.map(function (a) {
        return a.bookId
    };

    return BooksCollection
    .find({_id : {$in: bookIds}})
    .sort({timestamp: -1})
    .then(function(books){

     for(var i = 0; i < books.length; i++){
        for(var j = 0; j < favorites.length; j++){
          if(favorites[j].bookId  == books[i]._id){

           //'join' user's myRating to book document here
            books[i].userRating = favorites[j].myRating;  

           };
        };    
    };

      // return books array of objects with newly added UserRating property
      return books;

    });

});

Solution

The nested loops perform books.length * favorites.length iterations (up to 4 million).

Instead build a dictionary of id -> rating, so total iterations max is a sum of lengths.

var favRatings = {}, i, len;

for (i = 0, len = favorites.length; i < len; i++) {
    var fav = favorites[i];
    favRatings[fav.bookId] = fav.myRating;
}

for (i = 0, len = books.length; i < len; i++) {
    var book = books[i];
    var rating = favRatings[book._id];
    if (rating !== undefined) {
        book.userRating = rating;  
    }
}

Code Snippets

var favRatings = {}, i, len;

for (i = 0, len = favorites.length; i < len; i++) {
    var fav = favorites[i];
    favRatings[fav.bookId] = fav.myRating;
}

for (i = 0, len = books.length; i < len; i++) {
    var book = books[i];
    var rating = favRatings[book._id];
    if (rating !== undefined) {
        book.userRating = rating;  
    }
}

Context

StackExchange Code Review Q#139091, answer score: 3

Revisions (0)

No revisions yet.