简体   繁体   中英

Sequelize use LEFT JOINs instead of nested INNER JOIN for many-to-many association

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM