【问题标题】:Sequelize use LEFT JOINs instead of nested INNER JOIN for many-to-many associationSequelize 使用 LEFT JOIN 而不是嵌套的 INNER JOIN 进行多对多关联
【发布时间】:2018-03-22 00:00:03
【问题描述】:

我在 Sequelize (MySQL) 中设置了三个模型——Book、Author 和 Book_author(连接表)。我设置了以下关联:

Book.belongsToMany(Author,
  {
    through: Book_author,
    foreignKey: 'book_id'
  }
);
Author.belongsToMany(Book,
  {
    through: Book_author,
    foreignKey: 'author_id'
  }
);

当我尝试对 Book 模型进行 findAll 查询时,如下...

Book.findAll({
    include: [
      { model: Author
      }
    ]
  }).then(bookList => {
    // do something with the bookList
});

...它会生成一个原始 SQL 查询,该查询具有以下结构(我删除了各个属性以保持简洁):

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;

但是,嵌套的 INNER JOIN 使我的查询变慢。单独测试原始 SQL 查询时也是如此,因此这不是 Sequelize 问题。为了缓解这种情况,我希望原始 SQL 查询只使用 LEFT JOIN,如下所示:

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;

我需要如何更改 Sequelize 模型和/或 findAll includes 属性才能获得此结果?我试过在includes 属性中使用required: false,但这只会影响外部联接,而不是嵌套联接。有什么方法可以在不使用sequelize.query 的情况下做到这一点?感谢您的帮助!

【问题讨论】:

  • 你想到了吗?

标签: mysql sequelize.js


【解决方案1】:

您可以使用两个belongsTo 关联来代替belongsToMany

Book.hasMany(BookAuthor);
BookAuthor.belongsTo(Author);

const bookList = await Book.findAll({
    include: [{
        model: BookAuthor,
        required: false,
        include: [{
            model: Author,
            required: false 
        }]
    }]
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 2013-02-07
    • 2010-12-03
    • 1970-01-01
    • 2014-03-13
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多