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

LoopBack4中为每个Exercise模型对象获取单条关联AthletExerciseLog记录的实现方案

解决LoopBack关联查询中每个父对象仅返回一条最新关联记录的问题

你遇到的问题很典型:当前的limit: 1是对整个关联查询结果集做全局限制,而不是按每个exerciseid分组后各取1条。生成的SQL最后加了LIMIT 1,所以只会返回符合条件的第一条记录,自然只会对应一个exercise。

下面提供几种可行的解决方案,你可以根据自己的场景选择:

方法1:使用子查询筛选每个Exercise的最新日志

通过子查询,为每个Exercise单独筛选出其对应的最新AthletExerciseLog记录,再关联到主查询中:

exerciseController.find({
  include: [{
    relation: "athletExerciseLogsExercise",
    scope: {
      where: {
        userId: id,
        id: {
          // 使用参数化查询避免SQL注入,同时关联当前Exercise的id
          inq: [
            db.raw(`
              SELECT id FROM athletExerciseLog 
              WHERE exerciseId = ? AND userId = ?
              ORDER BY date DESC LIMIT 1
            `, [db.col('Exercise.id'), id])
          ]
        }
      }
    }
  }]
});

这种方式兼容性较好,大多数数据库都支持,而且能精准控制每个Exercise的最新记录。

方法2:使用窗口函数(ROW_NUMBER())分组取最新记录

利用数据库的窗口函数ROW_NUMBER(),按exerciseId分组并按date倒序排序,取每组的第一条记录:

exerciseController.find({
  include: [{
    relation: "athletExerciseLogsExercise",
    scope: {
      where: db.raw(`
        userId = ? 
        AND ROW_NUMBER() OVER (PARTITION BY exerciseId ORDER BY date DESC) = 1
      `, [id])
    }
  }]
});

窗口函数的性能通常比子查询更优,适合数据量较大的场景,不过要注意你的数据库是否支持窗口函数(比如PostgreSQL、MySQL 8.0+都支持)。

方法3:定义HasOne关联指向最新日志

如果你的业务经常需要获取每个Exercise的最新日志,可以直接在Exercise模型中定义一个hasOne关联,专门指向最新的那条记录:

export class Exercise extends Entity {
  ...
  @hasMany(() => AthletExerciseLog, {keyTo: 'exerciseId'})
  athletExerciseLogsExercise?: AthletExerciseLog[];

  // 新增hasOne关联,专门获取最新日志
  @hasOne(() => AthletExerciseLog, {
    keyTo: 'exerciseId',
    scope: {
      order: ['date DESC'],
      limit: 1
    }
  })
  latestAthletExerciseLog?: AthletExerciseLog;
  ...
}

查询时直接include这个新关联,并传入userId条件:

exerciseController.find({
  include: [{
    relation: "latestAthletExerciseLog",
    scope: {
      where: { userId: id }
    }
  }]
});

这种方式代码更简洁,语义更清晰,适合频繁使用该查询的场景。

注意事项

  • 无论用哪种方法,都要避免直接拼接字符串到SQL中,一定要用参数化查询(比如上面的db.raw带参数的写法),防止SQL注入。
  • 如果使用窗口函数,要确认你的数据库版本支持该特性(比如MySQL 5.x不支持窗口函数,需要升级到8.0+)。

内容的提问来源于stack exchange,提问作者el-niko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:23:08