How to select a specific column in typeorm many to many relationship

倖福魔咒の 提交于 2021-02-11 15:34:21

问题


I have an n:m relationship with a custom join table in TYPEORM.

Entity1

@Entity({ name: 'users' })
export class User extends BaseModel {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column({ type: 'varchar', length: 50 })
  @IsNotEmpty()
  username!: string;

  @Column({ unique: true, type: 'varchar', length: 50 })
  @IsEmail()
  @IsNotEmpty()
  email!: string;

  @CreateDateColumn({ type: 'timestamp' })
  createdAt!: Date;

  @UpdateDateColumn({ type: 'timestamp' })
  updatedAt!: Date;

  @DeleteDateColumn({ type: 'timestamp' })
  deletedAt!: Date;

  @OneToMany(
    (type) => UsersGameGroup,
    (userGameGroup) => userGameGroup.user,
    { cascade: true }
  )
  usersGameGroups!: UsersGameGroup[];
}

Entity2

@Entity({ name: 'game_groups' })
export class GameGroup extends BaseModel {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  title!: string;

  @OneToMany(
    (type) => UsersGameGroup,
    (userGameGroup) => userGameGroup.gameGroup,
    { cascade: true }
  )
  usersGameGroups!: UsersGameGroup[];
}

Entity3 a Join table

@Entity({ name: 'users_game_groups' })
export class UsersGameGroup extends BaseModel {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column({ type: 'int' })
  userId!: number;

  @Column({ type: 'int' })
  gameGroupId!: number;

  @ManyToOne(
    (type) => User,
    (user) => user.usersGameGroups,
    { onDelete: 'CASCADE' }
  )
  user!: User;

  @ManyToOne(
    (type) => GameGroup,
    (gameGroup) => gameGroup.usersGameGroups,
    { onDelete: 'CASCADE' }
  )
  gameGroup!: GameGroup;
}

and I'm querying gameGroup to get the users.

const gg = await GameGroup.findOneOrFail(gameGroupID, {
        select: ['id', 'title'],
        relations: ['usersGameGroups', 'usersGameGroups.user']
      });
const { id, title, createdAt, updatedAt, usersGameGroups } = gg;

but the problem here is it will return all the columns of the user. All I want is the username.

return sample:

{
  "meta": {},
  "payload": {
    "gameGroup": {
      "id": 2,
      "title": "game2",
      "users": {
        "id": 2,
        "title": "game2",
        "usersGameGroups": [
          {
            "id": 2,  <-this too I don't need this but whatever
            "userId": 1, <-this too I don't need this but whatever
            "gameGroupId": 2, <-this too I don't need this but whatever
            "createdAt": "2020-04-09T00:11:39.000Z", <-this too I don't need this but whatever
            "updatedAt": null, <-this too I don't need this but whatever
            "deletedAt": null, <-this too I don't need this but whatever
            "user": {
              "id": 1,
              "username": "new1",
              "email": "new1@gmail.com", <- I just need this
              "createdAt": "2020-04-09T00:09:45.000Z",
              "updatedAt": "2020-04-09T00:10:55.000Z",
              "deletedAt": null
            }
          },
          {
            "id": 3, <-this too I don't need this but whatever
            "userId": 2, <-this too I don't need this but whatever
            "gameGroupId": 2, <-this too I don't need this but whatever
            "createdAt": "2020-04-09T00:12:10.000Z", <-this too I don't need this but whatever
            "updatedAt": null, <-this too I don't need this but whatever
            "deletedAt": null, <-this too I don't need this but whatever
            "user": {
              "id": 2,
              "username": "new2", <- I just need this
              "email": "new2@gmail.com",
              "createdAt": "2020-04-09T00:09:51.000Z",
              "updatedAt": null,
              "deletedAt": null
            }
          }
        ]
      }
    }
  }
}

And if I query it like this. I include the user and its username like user.username

relations: ['usersGameGroups', 'usersGameGroups.user', 'user', 'user.username']

I get an error.

"Relation \"user\" was not found, please check if it is correct and really exist in your entity."

In raw SQL the query looks something like this.

SELECT
    u.username
FROM 
    users u
JOIN 
    users_game_groups ugg
ON ugg.userId = u.id
JOIN 
    game_groups gg
ON gg.id = ugg.gameGroupId
WHERE gg.id = 2;

I'm expecting a JSON response like this.

"gameGroup": {
      "id": 2,
      "title": "game2",
      "users": {
        "id": 2,
        "title": "game2",
        "usersGameGroups": [
          {
            "user": {
              "username": "new1",
            }
          },
            "user": {
              "username": "new2",
            }
          }
        ]
      }
    }

Thank you!! <3


回答1:


Ahh finally after trial and error, reading the actual codebase and a full amount of not giving up I finally got an answer.

const foo = await GameGroup.createQueryBuilder()
        .select(['gg.title', 'gg.id', 'ugg.id', 'u.username', 'u.email'])
        .from(GameGroup, 'gg')
        .innerJoin('gg.usersGameGroups', 'ugg')
        .innerJoin('ugg.user', 'u')
        .where({ id: gameGroupID })
        .getOne();

but I want it using active record.

something like:

const gg = await GameGroup.findOneOrFail(gameGroupID, {
        select: ['id', 'title', 'createdAt', 'updatedAt', 'usersGameGroups'],
        join: {
          alias: 'gg',
          innerJoinAndSelect: { ugg: 'gg.usersGameGroups', u: 'ugg.user' }
        }
});

but I cant select from here though. I cant do gg.usersGameGroups sigh :(



来源:https://stackoverflow.com/questions/61113589/how-to-select-a-specific-column-in-typeorm-many-to-many-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!