MySQL Sequelize 一次findAll搜索两张表
MySQL Sequelize searching two tables with one findAll
我创建了 3 个表
Products
|product_id | product_name|
|-----------|-------------|
|1 | coca cola |
|2 | pepsi |
|3 | orange |
Product_tags
|product_id | tag_id |
|-----------|--------|
|1 | 1 |
|2 | 1 |
|3 | 2 |
Tag_names
|tag_id | tag_name |
|-----------|----------|
|1 | soda |
|2 | juice |
使用:
db.products.belongsToMany(db.tag_names, { through: 'product_tags', as: "tags", foreignKey: 'product_id'});
db.tag_names.belongsToMany(db.products, {through: 'product_tags', as: "products", foreignKey: 'tag_id'});
现在我想通过产品名称或标签名称搜索这些表格。例如产品名称为“coca cola”,标签为“soda”,因此搜索“coca”或搜索“sod”都会 return 它,而“sod”也会 return “pepsi”。我似乎所能做的就是让它同时要求 product_name 和 tag_name 来匹配不是我想要的查询。
谢谢,
丹尼
到or
两个条件,你会想要使用[Op.or]
运算符。然后要从顶级 where 子句访问连接子句中的 table,有一个有趣的 dollar signs 语法可以派上用场。我不确定这是否正是您想要的,但它确实 return 可口可乐和百事可乐...我在 sequelize
版本 6 中针对 postgres
数据库测试了此查询
let result = await Product.findAll({
include: {
model: Tag,
as: 'tags',
required: true
},
where: {
[Op.or]: [
{ 'product_name': { [Op.like]: '%coca%' } },
{ '$tags.tag_name$': { [Op.like]: '%sod%' } }
]
}
})
并使用原始问题中的数据得出以下结果:
[
{
"product_id": 1,
"product_name": "coca cola",
"tags": [
{
"tag_id": 1,
"tag_name": "soda",
"product_tags": {
"createdAt": "2021-09-09T18:36:24.829Z",
"updatedAt": "2021-09-09T18:36:24.829Z",
"product_id": 1,
"tag_id": 1
}
}
]
},
{
"product_id": 2,
"product_name": "pepsi",
"tags": [
{
"tag_id": 1,
"tag_name": "soda",
"product_tags": {
"createdAt": "2021-09-09T18:36:24.861Z",
"updatedAt": "2021-09-09T18:36:24.861Z",
"product_id": 2,
"tag_id": 1
}
}
]
}
]
连同此查询:
SELECT "product"."product_id",
"product"."product_name",
"tags"."tag_id" AS "tags.tag_id",
"tags"."tag_name" AS "tags.tag_name",
"tags->product_tags"."created_at" AS "tags.product_tags.createdAt",
"tags->product_tags"."updated_at" AS "tags.product_tags.updatedAt",
"tags->product_tags"."product_id" AS "tags.product_tags.product_id",
"tags->product_tags"."tag_id" AS "tags.product_tags.tag_id"
FROM "products" AS "product" INNER JOIN (
"product_tags" AS "tags->product_tags" INNER JOIN "tags" AS "tags"
ON "tags"."tag_id" = "tags->product_tags"."tag_id"
) ON "product"."product_id" = "tags->product_tags"."product_id"
WHERE ("product"."product_name" LIKE '%coca%' OR
"tags"."tag_name" LIKE '%sod%');
我创建了 3 个表
Products
|product_id | product_name|
|-----------|-------------|
|1 | coca cola |
|2 | pepsi |
|3 | orange |
Product_tags
|product_id | tag_id |
|-----------|--------|
|1 | 1 |
|2 | 1 |
|3 | 2 |
Tag_names
|tag_id | tag_name |
|-----------|----------|
|1 | soda |
|2 | juice |
使用:
db.products.belongsToMany(db.tag_names, { through: 'product_tags', as: "tags", foreignKey: 'product_id'});
db.tag_names.belongsToMany(db.products, {through: 'product_tags', as: "products", foreignKey: 'tag_id'});
现在我想通过产品名称或标签名称搜索这些表格。例如产品名称为“coca cola”,标签为“soda”,因此搜索“coca”或搜索“sod”都会 return 它,而“sod”也会 return “pepsi”。我似乎所能做的就是让它同时要求 product_name 和 tag_name 来匹配不是我想要的查询。
谢谢,
丹尼
到or
两个条件,你会想要使用[Op.or]
运算符。然后要从顶级 where 子句访问连接子句中的 table,有一个有趣的 dollar signs 语法可以派上用场。我不确定这是否正是您想要的,但它确实 return 可口可乐和百事可乐...我在 sequelize
版本 6 中针对 postgres
数据库测试了此查询
let result = await Product.findAll({
include: {
model: Tag,
as: 'tags',
required: true
},
where: {
[Op.or]: [
{ 'product_name': { [Op.like]: '%coca%' } },
{ '$tags.tag_name$': { [Op.like]: '%sod%' } }
]
}
})
并使用原始问题中的数据得出以下结果:
[
{
"product_id": 1,
"product_name": "coca cola",
"tags": [
{
"tag_id": 1,
"tag_name": "soda",
"product_tags": {
"createdAt": "2021-09-09T18:36:24.829Z",
"updatedAt": "2021-09-09T18:36:24.829Z",
"product_id": 1,
"tag_id": 1
}
}
]
},
{
"product_id": 2,
"product_name": "pepsi",
"tags": [
{
"tag_id": 1,
"tag_name": "soda",
"product_tags": {
"createdAt": "2021-09-09T18:36:24.861Z",
"updatedAt": "2021-09-09T18:36:24.861Z",
"product_id": 2,
"tag_id": 1
}
}
]
}
]
连同此查询:
SELECT "product"."product_id",
"product"."product_name",
"tags"."tag_id" AS "tags.tag_id",
"tags"."tag_name" AS "tags.tag_name",
"tags->product_tags"."created_at" AS "tags.product_tags.createdAt",
"tags->product_tags"."updated_at" AS "tags.product_tags.updatedAt",
"tags->product_tags"."product_id" AS "tags.product_tags.product_id",
"tags->product_tags"."tag_id" AS "tags.product_tags.tag_id"
FROM "products" AS "product" INNER JOIN (
"product_tags" AS "tags->product_tags" INNER JOIN "tags" AS "tags"
ON "tags"."tag_id" = "tags->product_tags"."tag_id"
) ON "product"."product_id" = "tags->product_tags"."product_id"
WHERE ("product"."product_name" LIKE '%coca%' OR
"tags"."tag_name" LIKE '%sod%');