gpt4 book ai didi

javascript - 优化 Sequelize 中相关表的查询

转载 作者:太空宇宙 更新时间:2023-11-03 23:47:53 24 4
gpt4 key购买 nike

我想知道是否有更好的方法来获得以下结果:使用通过多对多关系连接的表中的值过滤行列表。在我的示例中,它是带有某些乐器的歌曲。

这是我的歌曲模型:

module.exports = function(sequelize, DataTypes) {
var Song = sequelize.define('songs', {
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
title: {
type: DataTypes.STRING(50),
allowNull: false
},
}, {
tableName: 'songs',
timestamps: false
});

Song.associate = function (models) {
Song.belongsToMany(models.instruments, {through: 'songs_instruments', foreignKey: 'song_id'})
};

return Song
};

这是我的仪器模型:

module.exports = function(sequelize, DataTypes) {
var Instrument = sequelize.define('instruments', {
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(50),
allowNull: false
}
}, {
tableName: 'instruments',
timestamps: false,
});

Instrument.associate = function (models) {
Instrument.belongsToMany(models.songs, {through: 'songs_instruments', foreignKey: 'instrument_id'})
};

return Instrument
};

这是连接表的模型:

module.exports = function(sequelize, DataTypes) {
return sequelize.define('songs_instruments', {
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
song_id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
references: {
model: 'songs',
key: 'id'
}
},
instrument_id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
references: {
model: 'instruments',
key: 'id'
}
}
}, {
tableName: 'songs_instruments',
timestamps: false
});
};

这是我当前获取数据的方式(args['instruments'] 包含我想要过滤歌曲的乐器列表):

const instruments = await db.instruments.findAll({
where: {name: args['instruments']}
})

const songs_instruments = await db.songs_instruments.findAll({
where: {instrument_id: instruments.map(instrument => instrument.id)}
})

const songs = await db.songs.findAll({
where: {id: songs_instruments.map(song => song.song_id)}
})
return songs

虽然这工作正常,并且最终我得到了我期望的结果,但我不禁想知道是否有更有效的方法来查询数据库,因为这样做总共会导致三个查询待执行:

Executing (default): SELECT `id`, `name` FROM `instruments` AS `instruments` WHERE `instruments`.`name` IN ('Vocals', 'Trumpet', 'Guitar');
Executing (default): SELECT `id`, `song_id`, `instrument_id` FROM `songs_instruments` AS `songs_instruments` WHERE `songs_instruments`.`instrument_id` IN (1, 3, 7);
Executing (default): SELECT `id`, `title` FROM `songs` AS `songs` WHERE `songs`.`id` IN (1, 1, 2, 2, 3, 3);

我对 Sequelize 还很陌生,因此我实现目标的方式可能不正确/次优。

最佳答案

哦,我完全错过了..已经晚了..是的,你可以这样做..添加如下所示的别名来为该连接添加别名,并在歌曲中执行相同的操作:“乐器”...您不需要获取连接记录..

Instrument.associate = function (models) {
Instrument.belongsToMany(models.songs, {through: 'songs_instruments', as: 'songs', foreignKey: 'instrument_id', otherKey: 'song_id'})
};

const instruments = await db.instruments.findAll({
where: {name: args['instruments']},
{
include: [{
model: db.songs,
as: 'songs',
through: db.songs_instruments,
}]
}
});

或者类似于下面包含的内容...

const songs = await db.songs.findAll({
include: [{
model: db.instruments,
as: 'instruments',
through: db.songs_instruments,
where: {name: args['instruments']}
}],
});

关于javascript - 优化 Sequelize 中相关表的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60368118/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com