У меня есть сценарий, в котором мне нужно вернуть некоторые вложенные реляционные данные, а также выполнить COUNT для другого отношения. В качестве примера я хочу вернуть блоги с массивом авторов для блога и 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,
  },
];

Я не могу отобразить articleCount с помощью getMany(), и getRaw() не будет вкладывать авторов.

Есть ли способ отобразить articleCount в приведенном выше или, возможно, использовать getRawMany для вложенности авторов?

Пример объекта:

interface Blog {
  id: string;
  name: string;
  authors: Author[];
  articles: Article[];
  articleCount?: number; // field is not mapped to db column
} 

Запрос:

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();

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"
0
Samuel Goldenbaum 22 Фев 2021 в 00:57

1 ответ

Лучший ответ

Вы можете использовать метод запроса .loadRelationCountAndMap для подсчета элементов вашего отношения.

Вот пример подсчета статей для каждого пользователя с помощью TypeOrm QueryBuilder:

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

Вы также можете сделать то же самое для конкретного пользователя:

async findUserById(id): Promise<UsersEntity> {
    return this.createQueryBuilder('user')
      .where('user.id=:id', { id })
      .leftJoin('user.articles', 'articles')
      .loadRelationCountAndMap('user.articlesCount', 'user.articles')
      .getOne();
}
1
Hugo Sohm 22 Фев 2021 в 16:04