Loopback4 中包含记录的限制

Limit for included records in Loopback4

我想查询运动模型对象并包含相关对象(关系:athletExerciseLogsExercise)。但我只需要 1 个相关对象,这就是为什么我将“限制:1”添加到包含范围:

exerciseController.find({
    include: [{
        relation: "athletExerciseLogsExercise",
        scope: {
            where: {
                userId: id
            },
            order: ['date DESC'],
            limit: 1
        }
    }, ]
});

型号

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

SQL(来自调试)

SELECT
  "id",
  "userid",
  "exerciseid",
  "date"
  ...
FROM
  "public"."athletexerciselog"
WHERE
  "userid" = '65b9b7110230'
  AND "exerciseid" IN (
    'd67503d511bb',
    '46d156a58aee'
  )
ORDER BY  "date" DESC
LIMIT 1

问题: SQL 结果仅包含 1 条记录 for one "exerciseid" = 'd67503d511bb'

问题:如何从“athletexerciselog”为每个“exerciseid”接收 1 条记录?

我找到了以下解决方案,这可能是一种开销,但我找不到其他方法...

1 - 创建数据库视图:select 每个 useridexerciseid[=14 只有 1(最后)条记录=]

CREATE VIEW "v_athletexerciselog" AS  
  SELECT q.*
  FROM athletexerciselog q
  WHERE (
        q.id IN ( 
          SELECT max(i.id) AS max
           FROM athletexerciselog i
          WHERE (i.event IS NULL)
          GROUP BY i.userid, i.exerciseid
        )
  )

2 - 创建新的 LB4 模型 和存储库 使用自定义 table 名称(视图名称)

扩展原始模型
@model({
  settings: {
    postgresql: {schema: 'public', table: 'v_athletexerciselog'}, // custom names
  },
})
export class VAthletExerciseLog extends AthletExerciseLog {
  constructor(data?: Partial<VAthletExerciseLog>) {
    super(data);
  }
}

3 - 将运动模型 和存储库 中的相关模型名称更改为 VAthletExerciseLog(新)

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

4 - 从查询中删除“order”和“limit”:

exercise.find({
    include: [{
        relation: "athletExerciseLogsExercise",
        scope: {
            where: {
                userId: id
            },
            //order: ['date DESC'],
            //limit: 1
        }
    }, ]
});