【问题标题】:filtering through M-M relationship in sequelize通过sequelize中的M-M关系过滤
【发布时间】:2022-12-05 06:47:23
【问题描述】:

我有下表,它们之间存在多对多关联。


内容模态.js

const Content = sequelize.define('Content', {
    title: DataTypes.STRING,
    name: DataTypes.TEXT,
    duration: DataTypes.INTEGER,
    ...
  }, {
    timestamps: true,
    paranoid: true,
  });

类别-modal.js

  const Category = sequelize.define('Category', {
    name: DataTypes.STRING,
    type: DataTypes.STRING,
  }, {
    timestamps: true, 
    paranoid: true,
  });

内容类别-modal.js

  const ContentCategory = sequelize.define('ContentCategory', {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    categoryId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: { model: 'Category', key: 'id' },
    },
    contentId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: { model: 'Content', key: 'id' },
    },
    categoryType: {
      type: DataTypes.STRING,
      allowNull: false
    }
  }, {});
  ContentCategory.associate = function(models) {
    models.Category.belongsToMany(models.Content, { through: ContentCategory });
    models.Content.belongsToMany(models.Category, { through: ContentCategory });
  };

这里每个内容都有固定的类别号。因此,每当我使用 JOIN 通过数据库查询其中一个类别时,我将只获得我已传递给 where 子句的类别。 例如说表中有以下字段:

目录

id title name
2 big_buck_bunny.mp4 1669976024371.mp4
3 newEra.mp4 1669976456758.mp4

分类表

id name type
6 Education topic
7 Animation style
8 Awareness topic
9 Narrative style

内容类别表

id contentId categoryId
4 3 6
5 3 7
6 2 8
7 2 7

在这里,当我使用以下 sequelize 查询过滤类别为动画的所有视频时:

//styleId=7, topicId=null
const { topicId, styleId } = req.query; 
return db.Content.findAll({
   include: [{ 
       model: db.Category,
       attributes: ['id', 'name', 'type'],
       where: { id: 7 }
   }],
})

我得到的内容只有与查询中预期的视频关联的两个类别之一:

data: [{
   "id": 2,
   "title": "big_buck_bunny.mp4",
   "name": "1669976024371.mp4",
   "Categories": [{
      "id": 7,
      "name": "Animation",
      "type": "style"
   }],
},
{
   "id": 3,
   "title": "newEra.mp4",
   "name": "1669976456758.mp4",
   "Categories": [{
      "id": 7,
      "name": "Animation",
      "type": "style"
   }],
}]

但是如果每个视频与查询的 categoryId 匹配,我想获取每个视频的所有类别。 IE。

data: [{
   "id": 2,
   "title": "big_buck_bunny.mp4",
   "name": "1669976024371.mp4",
   "Categories": [{
      "id": 7,
      "name": "Animation",
      "type": "style"
   },{
      "id": 8,
      "name": "Awareness",
      "type": "topic"
   }],
},
{
   "id": 3,
   "title": "newEra.mp4",
   "name": "1669976456758.mp4",
   "Categories": [{
      "id": 7,
      "name": "Animation",
      "type": "style"
   },{
      "id": 6,
      "name": "Education",
      "type": "topic"
   }],
}]

如果可以的话,请在答案或评论中分享。如果需要任何进一步的信息来澄清,请告诉我。我会在问题中添加它们。

笔记:如果什么都找不到,我的最后一个选择是查询所有数据,然后根据类别过滤它,但我认为这不是一个好的做法。

【问题讨论】:

    标签: mysql sequelize.js


    【解决方案1】:

    我建议再添加一个 m:n 关联到具有不同别名的相同表,但在这种情况下,这将是太多记录的乘法,您最终可能会遇到 out of memory 错误。因此,最好只获取满足条件的 Content 记录的 ID,然后使用给定的 ID 仅针对 Content 记录执行另一个类似的查询。

    const foundItems = await db.Content.findAll({
       attributes: ['id'],
       include: [{ 
           model: db.Category,
           attributes: ['id'],
           where: { id: 7 }
       }],
    })
    const itemWithAllCategories = db.Content.findAll({
       where: {
         id: foundItems.map(x => x.id)
       },
       include: [{ 
           model: db.Category,
           attributes: ['id', 'name', 'type'],
       }],
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多