Sequelize find based on association

前端 未结 3 1528
时光说笑
时光说笑 2020-12-23 19:53

How would I use Sequelize to find all people where a column in the relation satisfies a condition?

An example would be to find all Books whose author\'s last name is

3条回答
  •  一整个雨季
    2020-12-23 20:29

    For documentation!

    Check the eager loading section

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

    For the above answers! You can find it in the doc at the following title

    Complex where clauses at the top-level

    From the doc:

    To obtain top-level WHERE clauses that involve nested columns, Sequelize provides a way to reference nested columns: the '$nested.column$' syntax.

    It can be used, for example, to move the where conditions from an included model from the ON condition to a top-level WHERE clause.

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

    Generated 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';
    

    The $nested.column$ syntax also works for columns that are nested several levels deep, such as $some.super.deeply.nested.column$. Therefore, you can use this to make complex filters on deeply nested columns.

    For a better understanding of all differences between the inner where option (used inside an include), with and without the required option, and a top-level where using the $nested.column$ syntax, below we have four examples for you:

    // 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
      }
    });
    

    Generated SQLs, in order:

    -- 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';
    

    And that give us a good look how the join's are done!

提交回复
热议问题