I have three models set up in Sequelize (MySQL)--Book, Author, and Book_author (join table). I have the following associations set up:
Book.belongsToMany(Author,
{
through: Book_author,
foreignKey: 'book_id'
}
);
Author.belongsToMany(Book,
{
through: Book_author,
foreignKey: 'author_id'
}
);
When I attempt a findAll query on the Book model, as follows...
Book.findAll({
include: [
{ model: Author
}
]
}).then(bookList => {
// do something with the bookList
});
...it produces a raw SQL query that has the following structure (I've removed the individual attributes to keep things concise):
SELECT book.*, author.* FROM book
LEFT JOIN (author
INNER JOIN book_author
ON author.author_id = book_author.author_id)
ON book.book_id = book_author.book_id;
However, the nested INNER JOIN is making my query slow. This is also the case when testing the raw SQL query alone, so it's not a Sequelize issue. To mitigate this, I would like the raw SQL query to instead only use LEFT JOINs, as follows:
SELECT book.*, author.* FROM book
LEFT JOIN book_author
ON book.book_id = book_author.book_id
LEFT JOIN author
ON author.author_id = book_author.author_id;
How would I need to change the Sequelize models and/or the findAll includes
property to get this result? I've tried using required: false
in the includes
property, but that only affects the outer JOIN, not the nested one. Is there any way to do this without using sequelize.query
? Thank you for any assistance!
You can use two belongsTo
associations instead of belongsToMany
:
Book.hasMany(BookAuthor);
BookAuthor.belongsTo(Author);
const bookList = await Book.findAll({
include: [{
model: BookAuthor,
required: false,
include: [{
model: Author,
required: false
}]
}]
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.