Sequelize接收空数组,同时在顶层进行关联过滤

Posted

技术标签:

【中文标题】Sequelize接收空数组,同时在顶层进行关联过滤【英文标题】:Sequelize receiving empty array while filtering with association at top level 【发布时间】:2021-05-09 18:01:13 【问题描述】:

续集版本:6.6.2

上下文

我有 3 个模型:UserFoodUserFoods。他们之间使用documentation 建立了超级多对多的关系。

const User = sequelize.define('user', 
  username: DataTypes.STRING,
);

const Food = sequelize.define('food', 
  name: DataTypes.STRING
);

const UserFoods = sequelize.define('user_foods', 
  id: 
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
    allowNull: false
  ,
  status: DataTypes.INTEGER,
);

User.belongsToMany(Food,  through: UserFoods );
Food.belongsToMany(User,  through: UserFoods );
User.hasMany(UserFoods);
UserFoods.belongsTo(User);
Food.hasMany(UserFoods);
UserFoods.belongsTo(Food);

当向用户添加食物时,UserFoods 中的status 列将收到一个数字,该数字将用于创建用户食物列表(最喜欢的、好的、糟糕的...)。

这样我可以这样查询:

const foods = await UserFoods.findAll(
  where:  userId: req.userId, status: 1 ,
  include: Food,
);

问题

现在我正在尝试查询所有不在用户列表中的食物。我正在做以下事情:

const foods = await Food.findAll(
  where: 
    "$user_foods.userId$":  [Op.not]: req.userId ,
  ,
  include: 
    model: UserFoods,
    duplicating: false,
  ,
  limit: 10,
);

// output foods: [] 

为什么我收到一个空数组?

如果我将Op.not 更改为Op.eq,它将返回属于该用户的所有食物,那么为什么不反过来呢?

【问题讨论】:

【参考方案1】:

使用Op.ne 代替Op.not

where: 
    "$user_foods.userId$":  [Op.ne]: req.userId ,
  ,

【讨论】:

我得到了与Op.ne相同的空数组【参考方案2】:

我发现了一个关于 SQL 连接的 question,它建议在第二个表的键上使用 null。

const foods = await Food.findAll(
  where: 
    [Op.or]: [
       "$user_foods.userId$":  [Op.ne]: req.userId  ,
       "$user_foods.userId$":  [Op.is]: null  ,
    ]
  ,
  include: 
    model: UserFoods,
    duplicating: false,
  ,
  limit: 10,
);

所以对于有用户关联的食物,只返回与当前用户没有关联的食物。

返回所有没有任何关联用户的 Foods。

这是可行的,但我不确定是否是最好的方法,因为我在 Sequelize 和 SQL 方面没有太多经验。

【讨论】:

以上是关于Sequelize接收空数组,同时在顶层进行关联过滤的主要内容,如果未能解决你的问题,请参考以下文章

Sequelize:急切加载和排序(在父表上)

为啥 Sequelize 认为我的模型没有关联?

如何在 Dojo 中迭代对象(关联数组)?

Sequelize models - 在 Node 中同步时设置关联

Sequelize:模型未关联到 Model2

sequelize的关联