如何在sequelize中实现`join on and`?

How to implement `join on and` in sequelize?

这是我想要的:

create table a(
 id int primary key,
 bid int ,
 type int
)

create table b(
 id int primary key,
 name varchar(255)
)

select * from a inner join b on a.bid = b.id and a.type = 3

我知道像这样的集合关联:

ModelA.belongsto(ModelB,{foreignKey:"bid"})

ModelA.findAll({
    include:[
       model:ModelB
    ]
})

但是如何指定第二个条件and a.type = 3

options.include 中指定 where 子句。

例如:

import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';

class A extends Model {}
A.init(
  {
    bid: DataTypes.INTEGER,
    type: DataTypes.INTEGER,
  },
  { sequelize, tableName: 'a' },
);

class B extends Model {}
B.init(
  {
    name: DataTypes.STRING(255),
  },
  { sequelize, tableName: 'b' },
);

A.belongsTo(B, { foreignKey: 'bid' });
B.hasMany(A, { foreignKey: 'bid' });

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await B.bulkCreate(
      [
        { name: 'x', As: [{ bid: 1, type: 1 }] },
        { name: 'y', As: [{ bid: 1, type: 2 }] },
        { name: 'z', As: [{ bid: 2, type: 3 }] },
        { name: 't', As: [{ bid: 3, type: 3 }] },
      ],
      { include: [A] },
    );
    // test
    const data = await A.findAll({
      include: [
        {
          model: B,
          where: {
            '$A.type$': 3,
          },
        },
      ],
      raw: true,
    });
    console.log(data);
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

执行结果:

Executing (default): DROP TABLE IF EXISTS "a" CASCADE;
Executing (default): DROP TABLE IF EXISTS "b" CASCADE;
Executing (default): DROP TABLE IF EXISTS "b" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "b" ("id"   SERIAL , "name" VARCHAR(255), PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'b' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "a" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "a" ("id"   SERIAL , "bid" INTEGER REFERENCES "b" ("id") ON DELETE NO ACTION ON UPDATE CASCADE, "type" INTEGER, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'a' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "b" ("id","name") VALUES (DEFAULT,'x'),(DEFAULT,'y'),(DEFAULT,'z'),(DEFAULT,'t') RETURNING *;
Executing (default): INSERT INTO "a" ("id","bid","type") VALUES (DEFAULT,1,1),(DEFAULT,2,2),(DEFAULT,3,3),(DEFAULT,4,3) RETURNING *;
Executing (default): SELECT "A"."id", "A"."bid", "A"."type", "B"."id" AS "B.id", "B"."name" AS "B.name" FROM "a" AS "A" INNER JOIN "b" AS "B" ON "A"."bid" = "B"."id" AND "A"."type" = 3;
[
  { id: 3, bid: 3, type: 3, 'B.id': 3, 'B.name': 'z' },
  { id: 4, bid: 4, type: 3, 'B.id': 4, 'B.name': 't' }
]

查看数据库中的数据记录: