网站搜索

typescript - 在聚合列上使用 typeorm 排序


我有两张表:user 和 activity,它们有 @OneToMany 关系。

我必须编写一个查询来统计用户的活动,并返回时可以排序。我不知道它将如何排序,因此我必须在所有字段上启用排序,包括activityCount。

我尝试使用 loadRelationCountAndMap 来做类似这样的事情

async getUsersAndCount(
    skip: number,
    limit: number,
    orderBy: string,
    orderOptions: OrderByOptions,
    query?: [string, ObjectLiteral][]
): Promise<[User[], number]> {
    const initialQuery =  this.createInitialQuery();

    if (query && query.length > 0) {
        query.forEach(q => initialQuery.andWhere(q[0], q[1]));
    }

    return await initialQuery.orderBy(orderBy, orderOptions)
        .offset(skip)
        .limit(limit)
        .printSql()
        .getManyAndCount();
}

private createInitialQuery(): SelectQueryBuilder<User> {
    return this.createQueryBuilder('user')
        .loadRelationCountAndMap('activityCount', 'user.activity', 'activityCount')
        .where('user.status = 1')
        .addGroupBy('user.id');

但是我不能按 activityCount 字段排序。

然后我尝试使用子查询,但它无法创建按 userId 在活动表上进行连接的查询。

然后我尝试使用像这样的普通 SQL 查询:

await this.query(
        'SELECT u."id"                AS "user_id",\n' +
        '       u."telegram_id"       AS "user_telegram_id",\n' +
        '       u."telegram_username" AS "user_telegram_username",\n' +
        '       COUNT(a.id)           AS activityCount\n' +
        'FROM "user" u\n' +
        'INNER JOIN activity a ON a."userId" = u.id\n' +
        'WHERE u."status" = 1\n' +
        'GROUP BY u."id"\n' +
        `ORDER BY $1 $2\n` +
        `OFFSET $3\n` +
        `LIMIT $4`);

带有参数 order by、order direction、limit 和 offset,但是 typeorm 没有填充这些参数,我收到了 syntax error near $2。

我可以连接字符串来填充参数,但这将是非常糟糕的方式。

我也可以使用 VIEW 来解决这个问题,但可能还有其他方法?