TypeORM:如何在使用 getMany() 时添加 COUNT 字段

Sam*_*l G 2 typeorm

我有一个场景,我需要返回一些嵌套关系数据并对另一个关系执行 COUNT。例如,我想返回博客,其中包含博客的作者数组以及博客包含的文章计数:

[
  {
    id: 1,
    name: 'Blog 1',
    authors: [
      {
        id: 1,
        name: 'Author 1',
      },
      {
        id: 2,
        name: 'Author 2',
      },
    ],
    articleCount: 5,
  },
  {
    id: 2,
    name: 'Blog 2',
    authors: [
      {
        id: 2,
        name: 'Author 2',
      },
      {
        id: 3,
        name: 'Author 3',
      },
    ],
    articleCount: 2,
  },
];
Run Code Online (Sandbox Code Playgroud)

我似乎无法映射articleCountusing getMany(),并且getRaw()不会嵌套作者。

有没有办法映射articleCount上面的内容,或者可能使用getRawMany嵌套作者?

示例实体:

interface Blog {
  id: string;
  name: string;
  authors: Author[];
  articles: Article[];
  articleCount?: number; // field is not mapped to db column
} 
Run Code Online (Sandbox Code Playgroud)

询问:

const results = await repository.createQueryBuilder('blog')
  .select([
    'blog.id',
    'blog.name',
    'author.id',
    'author.name',
  ])
  .addSelect('COUNT(article.id)', 'blog_articleCount') // trying to map this to the entity
  .leftJoin('blog.authors', 'author')
  .leftJoin('blog.articles', 'article')
  .groupBy('blog.id')
  .addGroupBy('blog.name')
  .addGroupBy('author.id')
  .addGroupBy('author.name')
  .getMany();
Run Code Online (Sandbox Code Playgroud)

SQL:

SELECT "blog"."id" AS "blog_id",
    "blog"."name" AS "blog_name",
    "author"."id" AS "author_id",
    "author"."name" AS "author_name",
    COUNT("article"."id") AS "blog_articleCount"
FROM "blogs" "blog"
LEFT JOIN "blog__authors" "blog_author" ON "blog_author"."blogsId" = "blog"."id"
LEFT JOIN "authors" "author" ON "author"."id" = "blog_author"."authorsId"
LEFT JOIN "articles" "article" ON "article"."blog_id" = "blog"."id"
GROUP BY "blog"."id",
    "blog"."name",
    "author"."id",
    "author"."name"
Run Code Online (Sandbox Code Playgroud)

Hug*_*ohm 11

您可以使用.loadRelationCountAndMap查询方法对关系中的元素进行计数。

以下是使用 TypeOrm QueryBuilder 计算每个用户的文章数量的示例:

async findUsers(): Promise<UsersEntity[]> {
    return this.createQueryBuilder('user')
      .leftJoin('user.articles', 'articles')
      .loadRelationCountAndMap('user.articlesCount', 'user.articles')
      .getMany();
}
Run Code Online (Sandbox Code Playgroud)

您还可以对特定用户执行相同的操作:

async findUserById(id): Promise<UsersEntity> {
    return this.createQueryBuilder('user')
      .where('user.id=:id', { id })
      .leftJoin('user.articles', 'articles')
      .loadRelationCountAndMap('user.articlesCount', 'user.articles')
      .getOne();
}
Run Code Online (Sandbox Code Playgroud)