通过ID数组获取数据

问题描述

我正在尝试为我的项目制作过滤歌曲,我有一系列从客户端获取的流派ID,我这样做是为了从一个ID中获取所有音频:

Audio.findAll({
  include: [{
    model: db.Genres,as: "genres",where: {
      id: {
        [Op.and]: [1]
      }
    },}]
})

但是我需要从各种流派/ mods id数组中获取所有音频,还希望通过流派ids和mods ids过滤音频,但是我不知道该怎么做,知道吗?

歌曲模型

const Audio =  sequelize.define('Audio',{
  id: {
    autoIncrement: true,type: DataTypes.INTEGER(30),allowNull: false,primaryKey: true
  },name: {
    type: DataTypes.STRING(255),allowNull: false
  },})
Audio.associate = function(models) {
  Audio.belongsToMany(models.Genres,{through: 'AudioGenres',foreignKey: 'id_audio',as: 'genres'})
  Audio.belongsToMany(models.Mods,{through: 'AudioMods',as: 'mods'})
}

AudioGenreModel

const AudioGenres =  sequelize.define('AudioGenres',{
  id_audio: {
    type: DataTypes.INTEGER(11),primaryKey: true,references: {
      model: 'Audio',key: 'id'
    }
  },id_genre: {
    type: DataTypes.INTEGER(11),references: {
      model: 'Genres',key: 'id'
    }
})
AudioGenres.associate = function(models) {
  AudioGenres.belongsTo(models.Audio,{foreignKey: 'id_audio'})
  AudioGenres.belongsTo(models.Genres,{foreignKey: 'id_genre'})
};

AudioModModel

const AudioMods =  sequelize.define('AudioMods',id_mod: {
    type: DataTypes.INTEGER(11),references: {
      model: 'Mods',key: 'id'
    }
})
AudioMods.associate = function(models) {
  AudioMods.belongsTo(models.Audio,{foreignKey: 'id_audio'})
  AudioMods.belongsTo(models.Mods,{foreignKey: 'id_mod'})
};

Mods and Genres Model

const Mods =  sequelize.define('Mods',})
Mods.associate = function(models) {
  Mods.belongsToMany(models.Audio,foreignKey: 'id_mod',as: 'audios'})
}

const Genres =  sequelize.define('Genres',})
Genres.associate = function(models) {
  Genres.belongsToMany(models.Audio,foreignKey: 'id_genre',as: 'audios'})
}

解决方法

在查找值数组中的列时,应使用Op.in查询运算符。定义中的许多字段都将使用关系自动创建,对于AudioGenresAudioMods,您最初可以不使用任何字段来创建它们。

// only define name,others will be generated
const Audio =  sequelize.define('Audio',{
  name: {
    type: DataTypes.STRING(255),allowNull: false
  },});
Audio.associate = function(models) {
  Audio.belongsToMany(models.Genres,{ as: 'genres',through: 'AudioGenres',foreignKey: 'id_audio' })
  Audio.belongsToMany(models.Mods,{ as: 'mods',through: 'AudioMods',foreignKey: 'id_audio' })
}

const Genres =  sequelize.define('Genres',});
Genres.associate = function(models) {
  Genres.belongsToMany(models.Audio,{ as: 'audios',foreignKey: 'id_genre' })
}

const Mods =  sequelize.define('mods',});
Mods.associate = function(models) {
  Mods.belongsToMany(models.Audio,foreignKey: 'id_mod' })
}

// create empty table,relationships added automatically
const AudioGenres = sequelize.define('AudioGenres',{},{ timestamps: false });
const AudioMods = sequelize.define('AudioMods',{ timestamps: false }); 

使用Op.in查询运算符,用于表联接的数组。

// use the Sequelize.Op query operators,specifically Op.in
const { Op } = require('sequelize');

// these are the values to use for the joins.
const myArrayOfGenreIds = [1,2,...];
const myArrayOfModIds = [1,...];

查询将数组中的ID的两个表连接起来的数组中的值,并返回其中一个不为null的结果。

// now query for Audios joined to Genres and Mods through relationship tables
const audios = await Audio.findAll({
  include: [
    {
      model: Genres,as: 'genres',attributes: [],where: {
        id: {
          [Op.in]: myArrayOfGenreIds,},{
      model: Mods,as: 'mods',where: {
        id: {
          [Op.in]: myArrayOfModIds,],// only return results from Audios
  group: [sequelize.col('audios.id')],having: {
    // check to see if the count of IDs we got back matches the count we expect
    [Op.and]: [
      sequelize.where(
        sequelize.fn('COUNT',sequelize.col('genres.id')),myArrayOfGenreIds.length)
      ),sequelize.where(
        sequelize.fn('COUNT',sequelize.col('mods.id')),myArrayOfModIds.length)
      ),});