Sequelize基于关联查找

fut*_*pal 35 node.js sequelize.js

我如何使用Sequelize查找关系中的列满足条件的所有人?

一个例子是找到作者姓氏为"希区柯克"的所有书籍.书架构包含与作者表的hasOne关系.

编辑:我理解如何使用原始SQL查询完成此操作,但寻找另一种方法

c.h*_*ill 28

下面是如何将用户Sequelize让所有工作示例BooksAuthor具有一定的姓氏.它看起来比它复杂得多,因为我定义了模型,关联它们,与数据库同步(创建它们的表),然后在这些新表中创建虚拟数据.findAll在代码中间查找具体内容,了解您所追求的内容.

    module.exports = function(sequelize, DataTypes) {

    var Author = sequelize.define('Author', {

        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        firstName: {
            type: DataTypes.STRING
        },
        lastName: {
            type: DataTypes.STRING
        }

    })

    var Book = sequelize.define('Book', {

        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        title: {
            type: DataTypes.STRING
        }

    })

    var firstAuthor;
    var secondAuthor;

    Author.hasMany(Book)
    Book.belongsTo(Author)

    Author.sync({ force: true })
        .then(function() {
            return Book.sync({ force: true });
        })
        .then(function() {
            return Author.create({firstName: 'Test', lastName: 'Testerson'});
        })
        .then(function(author1) {
            firstAuthor=author1;
            return Author.create({firstName: 'The Invisible', lastName: 'Hand'});
        })
        .then(function(author2) {
            secondAuthor=author2
            return Book.create({AuthorId: firstAuthor.id, title: 'A simple book'});
        })
        .then(function() {
            return Book.create({AuthorId: firstAuthor.id, title: 'Another book'});
        })
        .then(function() {
            return Book.create({AuthorId: secondAuthor.id, title: 'Some other book'});
        })
        .then(function() {
            // This is the part you're after.
            return Book.findAll({
                where: {
                   'Authors.lastName': 'Testerson'
                },
                include: [
                    {model: Author, as: Author.tableName}
                ]
            });
        })
        .then(function(books) { 
            console.log('There are ' + books.length + ' books by Test Testerson')
        });
  }
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说不起作用,我认为从sequelize 2.0开始,where子句必须放在include数组成员中,例如`include:[{model:...,where:...}]` (16认同)
  • 将`where`放在`include`里面构建一个这样的查询:`LEFT OUTER JOIN作者ON Books.authorId = Authors.id和Authors.lastName ='Testerson'`,结果与`LEFT OUTER JOIN Books.authorId = Authors.id ... WHERE Authors.lastName ='Testerson'.我不知道如何用sequelize实现后一个查询. (14认同)
  • 我可以证实,作为Sequelize 2.0的`where`子句必须是`include`内,就像:`包括:[{模型:..},其中:{"Author.lastName: 'Testerson'}]` (2认同)

Ada*_*dam 19

在最新版本的 Sequilize (5.9.0) 中,@c.hill 提出的方法不起作用。

现在您需要执行以下操作:

return Book.findAll({
    where: {
        '$Authors.lastName$': 'Testerson'
    },
    include: [
        {model: Author, as: Author.tableName}
    ]
});
Run Code Online (Sandbox Code Playgroud)

  • 当我用 Sequelize 花了 2 个小时来完成这个任务时,我怀念老式的普通 SQL (3认同)
  • 我在哪里可以找到这方面的文档? (2认同)
  • @lordvcs 这里:https://sequelize.org/master/manual/eager-loading.html#complex-where-clauses-at-the-top-level (2认同)

Moh*_*lal 8

对于文档!

检查急切加载部分

https://sequelize.org/master/manual/eager-loading.html

对于以上答案!您可以在以下标题的文档中找到它

顶层的复杂 where 子句

从文档:

为了获得涉及嵌套列的顶级 WHERE 子句,Sequelize 提供了一种引用嵌套列的方法:'$nested.column$' 语法。

例如,它可用于将 where 条件从包含的模型从 ON 条件移动到顶级 WHERE 子句。

User.findAll({
  where: {
    '$Instruments.size$': { [Op.ne]: 'small' }
  },
  include: [{
    model: Tool,
    as: 'Instruments'
  }]
});
Run Code Online (Sandbox Code Playgroud)

生成的 SQL:

SELECT
  `user`.`id`,
  `user`.`name`,
  `Instruments`.`id` AS `Instruments.id`,
  `Instruments`.`name` AS `Instruments.name`,
  `Instruments`.`size` AS `Instruments.size`,
  `Instruments`.`userId` AS `Instruments.userId`
FROM `users` AS `user`
LEFT OUTER JOIN `tools` AS `Instruments` ON
  `user`.`id` = `Instruments`.`userId`
WHERE `Instruments`.`size` != 'small';
Run Code Online (Sandbox Code Playgroud)

为了更好地理解内部 where 选项(在包含中使用),有和没有必需选项,以及使用 $nested.column$ 语法的顶级之间的所有差异,下面我们为您提供了四个示例:

// Inner where, with default `required: true`
await User.findAll({
  include: {
    model: Tool,
    as: 'Instruments',
    where: {
      size: { [Op.ne]: 'small' }
    }
  }
});

// Inner where, `required: false`
await User.findAll({
  include: {
    model: Tool,
    as: 'Instruments',
    where: {
      size: { [Op.ne]: 'small' }
    },
    required: false
  }
});

// Top-level where, with default `required: false`
await User.findAll({
  where: {
    '$Instruments.size$': { [Op.ne]: 'small' }
  },
  include: {
    model: Tool,
    as: 'Instruments'
  }
});

// Top-level where, `required: true`
await User.findAll({
  where: {
    '$Instruments.size$': { [Op.ne]: 'small' }
  },
  include: {
    model: Tool,
    as: 'Instruments',
    required: true
  }
});
Run Code Online (Sandbox Code Playgroud)

生成的 SQL,按顺序:

-- Inner where, with default `required: true`
SELECT [...] FROM `users` AS `user`
INNER JOIN `tools` AS `Instruments` ON
  `user`.`id` = `Instruments`.`userId`
  AND `Instruments`.`size` != 'small';

-- Inner where, `required: false`
SELECT [...] FROM `users` AS `user`
LEFT OUTER JOIN `tools` AS `Instruments` ON
  `user`.`id` = `Instruments`.`userId`
  AND `Instruments`.`size` != 'small';

-- Top-level where, with default `required: false`
SELECT [...] FROM `users` AS `user`
LEFT OUTER JOIN `tools` AS `Instruments` ON
  `user`.`id` = `Instruments`.`userId`
WHERE `Instruments`.`size` != 'small';

-- Top-level where, `required: true`
SELECT [...] FROM `users` AS `user`
INNER JOIN `tools` AS `Instruments` ON
  `user`.`id` = `Instruments`.`userId`
WHERE `Instruments`.`size` != 'small';
Run Code Online (Sandbox Code Playgroud)

这让我们可以很好地了解join是如何完成的!