You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Sequelize实现双LEFT OUTER JOIN获取关联用户与好友完整数据

解决Sequelize双LEFT OUTER JOIN关联同一张表的问题

嘿,我之前刚踩过这个坑!要同时拉取好友关系里双方的完整用户数据,核心是给同一张表的两次关联设置不同的别名,这样Sequelize才能区分开两个JOIN的对象。下面一步步来:

第一步:先正确定义模型关联

首先你需要在Friends模型里,和Users表建立两个独立的关联,分别对应userId(发起好友关系的用户)和idFriend(被关联的好友),一定要给每个关联起独特的别名:

// 假设你的Users模型叫User,Friends模型叫Friend
const User = require('./user.model');
const Friend = require('./friend.model');

// 关联1:Friend表的userId关联User表的id,别名为'initiator'(发起者)
Friend.belongsTo(User, {
  foreignKey: 'userId',
  as: 'initiator',
  onDelete: 'CASCADE'
});

// 关联2:Friend表的idFriend关联User表的id,别名为'friend'(好友)
Friend.belongsTo(User, {
  foreignKey: 'idFriend',
  as: 'friend',
  onDelete: 'CASCADE'
});

第二步:编写带双LEFT JOIN的查询

接下来就可以用findAll方法,通过include同时引入这两个关联,再加上筛选条件(用户ID=23,不管是发起者还是好友):

const { Op } = require('sequelize'); // Sequelize v6+ 需要单独引入Op

async function getFriendshipsWithUsers(userId) {
  return await Friend.findAll({
    where: {
      [Op.or]: [
        { userId: userId },
        { idFriend: userId }
      ]
    },
    // 同时包含两个关联的用户数据
    include: [
      {
        model: User,
        as: 'initiator',
        attributes: ['id', 'username', 'email'] // 指定要返回的字段,也可以用exclude排除不需要的
      },
      {
        model: User,
        as: 'friend',
        attributes: ['id', 'username', 'email']
      }
    ],
    raw: false, // 保持Sequelize实例格式,想要纯JSON可以设为true
    nest: true // 把关联的数据嵌套到对应的别名字段下,结构更清晰
  });
}

// 调用示例:查询用户23的所有好友关系及双方信息
const result = await getFriendshipsWithUsers(23);
console.log(result);

关键注意点

  • 别名as必须和关联定义、查询时的include里的as完全一致,否则Sequelize会找不到关联
  • belongsTo默认生成的就是LEFT OUTER JOIN,不需要额外配置
  • 如果是Sequelize v5及以下版本,Op的引入方式是const Op = Sequelize.Op,记得调整

这样返回的结果里,每条好友记录都会包含initiator和friend两个对象,分别对应双方的完整用户数据啦!

内容的提问来源于stack exchange,提问作者tetar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:30:01