How to query based on a field in a referenced document?

Working in Node Express with Mongoose, I have a collection of books and a collection of book instances like this:

var BookSchema = new Schema({
    title: { type: String, required: true },
    author: { type: Schema.Types.ObjectId, ref: 'Author', required: true },
   isbn: { type: String, required: true },
});

var BookInstanceSchema = new Schema({
    book: { type: Schema.Types.ObjectId, ref: 'Book', required: true },
    status: { type: String, required: true, enum: ['Available', 'Maintenance', 'Loaned', 'Reserved'], default: 'Maintenance' },
    due_back: { type: Date, default: Date.now }
});

I would like to find the book instances for a given book title. This code is not working.


// Book instances home POST (search results)
exports.bookinstance_home_post = function (req, res, next) {
    var moduleName = 'Book Copies';
    var search_for = RegExp('^' + req.body.book_title, 'i');
    var foundBook = Book.findOne({"title" : search_for});
    // I expected foundBook to be a document, but it's not.
    BookInstance
        .find({ "book": foundBook._id })
        .sort({ status: 1 })
        .exec(function (err, bookList) {
            if (err) { return next(err); }
            res.render('bookinstance_home', { title: moduleName, book_list: bookList })
        });
};

How can I query based on a field in a referenced document?

Ok, here’s how to do it, or at least one way. We search for the book and then search for the book instances within that search. This nesting gets confusing real fast, so now I need to check out callbackhell.com. :grinning:

// Book instances home POST (search results)
exports.bookinstance_home_post = function (req, res, next) {
    var moduleName = 'Book Copies';
    var search_for = RegExp('^' + req.body.book_title, 'i');
    Book
        .findOne({"book" : search_for})
        .exec(function (err, theBook) {
            if (err) {return next(err) }
            BookInstance
                .find({"book" : ObjectId(theBook._id)})
                .sort({ status: 1 })
                .exec( function (err, results) {
                    if (err) { return next(err); }
                    // Successful, so render.
                    res.render('bookinstance_home', { title: moduleName, book: req.body.book_title, copies: results });
            })
    })
};