3

Sorry if the title itself is a contradiction :) JS beginner here..

I get an array of MongoDB documents and I want to extend each one with another object (from another table) so that I can pass this array of extended objects to my view. I want to achieve something like this:

exports.myFunction = function(req, res) {
    Book.find({'good': true}).exec(function(err, docs) { // find good books
        // add authors to each book (?):
        for (var i = 0, i < docs.length; i++) {
            docs[i].author = Author.findOne({'_id': docs[i].author_id}); 
        }
        // render books:
        res.render('/books.ejs', {books: docs});
    });
}

I think this is not the JavaScript-way to do it :) So how can I achieve this?

Thanks,

2 Answers 2

2

Use the $lookup function as found in the aggregation framework. The following example demonstrates how you can apply that in your case:

exports.myFunction = function(req, res) {
    Book.aggregate([
        { "$match": { "good": true } },
        {
            "$lookup": {
                "from": "authors"
                "localField": "author_id",
                "foreignField": "_id",
                "as": "author"
            }
        },
        { "$unwind": "author" }
    ]).exec(function(err, docs) { 
        res.render('/books.ejs', {books: docs});
    });
}
Sign up to request clarification or add additional context in comments.

Comments

1

I found another solution, which is using populate.

For this, I needed to change my Book model,

from:

var mongoose = require('mongoose');

var bookSchema = mongoose.Schema({
author_id: String,
good: Boolean
});

to:

var mongoose = require('mongoose');
var Author = require('./author.js'); // added this

var bookSchema = mongoose.Schema({
author: { type: mongoose.Schema.Types.ObjectId, ref: 'Author' },
good: Boolean
});

And I chain populate() to my initial query as follows:

exports.myFunction = function(req, res) {
    Book.find({'good': true}).populate('author').exec(function(err, docs) { // find good books
        // render books:
        res.render('/books.ejs', {books: docs});
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.