【问题标题】:NestJS How to return array column to views in a databaseNestJS如何将数组列返回到数据库中的视图
【发布时间】:2022-01-26 10:43:49
【问题描述】:

我想在数据库中检索平台列表,每个平台检索该平台的项目。

看图

enter image description here

我使用 View Entities 来计算每个平台的进度。 我的问题是我们的每个平台项目都带有一个对象

enter image description here

如何从包含所有项目的平台返回对象?

【问题讨论】:

  • 嘿,我看到你是新来的。一些帮助我们帮助您的提示;英语可能不是您的第一语言,但请尝试校对您的问题是否有错误。您发布的链接中仍然有一些模板词。还可以尝试列出您尝试过的内容以及您在技术上的目标,最后,添加不适合您的代码,也许在 cmets 中添加一些伪代码以向我们展示您的意思。
  • 请提供足够的代码,以便其他人更好地理解或重现问题。
  • @Funonly 对不起我是新人,我添加了一个解释,希望这就足够了。
  • @Community 对不起我是新人,我添加了一个解释,希望这就足够了。

标签: postgresql nestjs typeorm


【解决方案1】:

我是 NestJs 的新手,我遇到了从后端返回响应实体的问题。 我使用了视图实体,因为我在复杂的 SQL 计算中作为平台推进计算。

使用视图时的问题,当包含多个项目和成员时,它会返回重复的对象。

如何返回包含项目和成员对象数组的平台对象?

我想要这样:

{
  "data": {
    "id": 1,
    "name": "Dev factory",
    "projects": [
      {
         "createdAt": "2022-01-11T10:29:42.000Z",
         "updatedAt": "2022-01-11T10:29:42.000Z",
         "deletedAt": null,
         "id": 2,
         "name": "API",
         "description": "efqzf",
        },{
         "createdAt": "2022-01-11T10:29:42.000Z",
         "updatedAt": "2022-01-11T10:29:42.000Z",
         "deletedAt": null,
         "id": 1,
         "name": "Web",
         "description": "efqsszf",
         }],
   "advancement": 50,
   "dueDate": null,
   "status": "In prograss"
}

下面的代码。

platform.entity.ts

import { Project } from '@routes/projects/entities/project.entity';
import { User } from '@routes/users/entities/user.entity';
import { ViewColumn, ViewEntity } from 'typeorm';

@ViewEntity({
  expression: `
SELECT 
      "platforms"."id" AS "id", 
      "platforms"."name" AS "name",
      "platforms"."releaseDate" AS "dueDate",
      "users"."id" AS "memberId",
      "users"."firstName" AS "memberFirstName",
      "users"."lastName" AS "memberLastName",
      ((cast(("done_tickets"."tickets_statusId") as float) / count ("tickets"."id")) * 100 ) AS "advancement" , 
      ("done_tickets"."tickets_statusId") AS "tickets_done", 
      count ("tickets"."id") AS  "tickets_count",
      CASE
        WHEN ((cast(("done_tickets"."tickets_statusId") as float) / count ("tickets"."id")) * 100 )>0 
            AND ((cast(("done_tickets"."tickets_statusId") as float) / count ("tickets"."id")) * 100 )<100 THEN 'In Progress'
        WHEN ((cast(("done_tickets"."tickets_statusId") as float) / count ("tickets"."id")) * 100 ) = 100 THEN  'Done'
        ELSE 'To Do'
      END AS status
FROM 
      "platforms" "platforms" 
LEFT JOIN 
        "users" AS "users" ON "platforms"."adminUserId" = "users"."id"
LEFT JOIN 
      "projects" "projects" ON "projects"."platformId"="platforms"."id" 
LEFT JOIN 
      "tickets" "tickets" ON "tickets"."projectId"="projects"."id" 
LEFT JOIN ( 
      SELECT "platforms"."id" AS "platformId" , 
          count ("tickets"."statusId") as "tickets_statusId" 
      FROM "platforms" "platforms" 
      LEFT JOIN "projects" "projects" ON "projects"."platformId"="platforms"."id" 
      LEFT JOIN "tickets" "tickets" ON "tickets"."projectId"="projects"."id" 
      LEFT JOIN "ticket_statuses" "status" ON  "status"."id"="tickets"."statusId" 
      WHERE "tickets"."statusId" = 5 
      GROUP BY "platforms"."id" ) "done_tickets" ON  "platforms"."id"="done_tickets"."platformId" 
LEFT JOIN "ticket_statuses" "status" ON "status"."id"="tickets"."statusId"  
GROUP BY "platforms"."id" , "done_tickets"."tickets_statusId" , "users"."id"
`,
})
export class ProgressPlatform {
  @ViewColumn()
  id!: number;

  @ViewColumn()
  name!: string;

  @ViewColumn()
  advancement!: Float64Array;

  @ViewColumn()
  dueDate!: Date;

  @ViewColumn()
  projects!: Project[]; <-- here is the problem

  @ViewColumn()
  members!: User[]; <-- here is the problem

  @ViewColumn()
  status!: string;
}

platform.service.ts

async findAll(
    options: PaginationParamsInterface,
  ): Promise<PaginatedInterface<ProgressPlatform>> {
    const [platforms, totalCount] = await Promise.all([
      this.platformsProgressRepository.find({
        skip: paginationUtils.getSkipCount(options.page, options.limit),
        take: paginationUtils.getLimitCount(options.limit),
      }),
      this.platformsProgressRepository.count(),
    ]);

    return { paginatedResult: platforms, totalCount };
  }

platform.controller.ts

  @ApiUnauthorizedResponse({ type: () => MessageResponseDto })
  @Version('1')
  @Get('all-platforms')
  @Serialize(AllPlatformsResponseDto)
  @ApiExtraModels(AllPlatformsResponseDto)
  @ApiQuery({ name: 'page', required: false })
  @ApiQuery({ name: 'limit', required: false })
  async findAll(@Query('page') page?: number, @Query('limit') limit?: number) {
    const paginatedTickets: PaginatedInterface<ProgressPlatform> =
      await this.platformsService.findAll({ page, limit });
    return responseUtils.success(
      'platforms',
      paginatedTickets.paginatedResult,
      {
        totalCount: paginatedTickets.totalCount,
      },
    );
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    相关资源
    最近更新 更多