[英]Use AND operation with many to many relationship in Sequelize
簡而言之,我的問題是:我想在聯接表中使用 AND 操作。 我認為這是現實生活中非常普遍的用例,但我還沒有找到任何相關的文章、博客或問題。 (我認為我的壞處:D)
讓我描述一個例子來說明我的意思:我想創建一個網上商店,我有一個手機和一個功能 model,它們之間存在多對多關系。 該功能有一個多選過濾器(在我的網站上),我想列出那些具有選定功能的手機。 (例如:A和B和C...)我想我不能創建一個查詢,因為列不能同時是 A 和 B,但我不確定。 例子:
const mobiles = await models.mobile.findAll({
where: '???',
attributes: ['id', 'name'],
include: [
{
model: models.feature,
where: '???',
attributes: ['id', 'name],
through: {
attributes: [],
},
},
],
});
我也對 Sequelize 和 SQL 解決方案感興趣。
示例模型和預期結果:
const Mobile = sequelize.define('Mobile', {
id: {
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
name: {
type: DataTypes.STRING
}
}, {});
const Feature = sequelize.define('Feature', {
id: {
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
name: {
type: DataTypes.STRING
}
}, {});
Mobile.belongsToMany(Feature, { through: 'MobileFeature' });
Feature.belongsToMany(Mobile, { through: 'MobileFeature' });
// Example Data in DB (from mobile context)
const exampleData = [
{
"id": 1,
"name": "Mobile1",
"features": [
{
"id": 1,
"name": "A",
},
{
"id": 2,
"name": "B",
},
{
"id": 3,
"name": "C",
},
],
},
{
"id": 2,
"name": "Mobile2",
"features": [],
},
{
"id": 3,
"name": "Mobile3",
"features": [
{
"id": 1,
"name": "A",
},
]
}
];
// Expected result
// Scenario: I want to list those mobiles which have A and C feature
const result = [
{
"id": 1,
"name": "Mobile1",
"features": [
{
"id": 1,
"name": "A",
},
{
"id": 2,
"name": "B",
},
{
"id": 3,
"name": "C",
},
]
},
];
我認為這里的查詢將比where
更復雜。
能否提供適合您問題的SQL查詢? 我想您將需要使用 GROUP BY、COUNT 和 HAVING(但這只是一個假設,按您的方式行事;))
如果我理解你的問題是正確的:加入移動和功能表。 然后在結果上使用where
WHERE: {
name: { [Op.or]: [A,B,C] } // here we pass array of selected feature names to where. It returns mobiles only with this features. But we are looking for mobile with ALL features passed in array)
}
按 Mobile.name 對其進行分組,計算每個手機中的功能,然后使用具有功能編號 = 用戶選擇的功能的手機(因此具有我們正在尋找的所有功能的手機)。
當然最后會是一個sequelize語句。
更新:在對此答案的評論中回答您的問題:
首先,您需要計算功能。 所以我們將使用COUNT
並將 output 存儲在CountedFeatures
列中:
attributes: ['id', 'name', [sequelize.fn('COUNT', 'table.fieldToCount'), 'CountedFeatures']],
然后您需要使用 group 對其進行group
。 使用示例:
group: ["table.name, table.id"]
然后您enter code here
having
使用之前創建countedFeatures
列:
having: sequelize.where(sequelize.fn('COUNT', 'countedFeatures'), '=', searchedFeaturesArray.length)
所以代碼結構看起來像這樣:
(...).findAll({
attributes: [...],
include : [
(...)
],
group: [...],
having: [...]
})
您還可以打開 SQL 語句日志記錄到控制台,看看下面到底發生了什么。 為此,在findAll
function 中添加logging: console.log
作為屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.