TypeORM:使用QueryBuilder选择具有嵌套关系的RANDOM()

时间:2020-09-28 22:32:17

标签: typescript nestjs query-builder typeorm

让我们说我有这些实体:

用户

@Entity('user', { synchronize: true })
export class UserEntity {

  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @OneToMany(type => PostEntity, post => post.user)
  posts: PostEntity[];

}

发布

@Entity('post', { synchronize: true })
export class PostEntity {

  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToOne(type => UserEntity , user => user.posts)
  @Index()
  user: UserEntity ;

  @Column({ nullable: true })
  text: string;
}

我要获取的是一个随机帖子及其相关用户,嵌套在对象的用户属性内。

使用实际的TypeORM存储库类,我可以轻松地做到这一点:

  public async getOnePost(): Promise<PostEntity> {
    return await this.findOneOrFail({
      relations: ['user']
    });

这将导致具有用户属性的PostEntity对象,该对象本身就是结构良好的UserEntity对象。

但是为了从数据库中获得随机行,看来我必须使用TypeORM QueryBuilder。我做了这样的事情:

const array = await this.createQueryBuilder()
  .select('*')
  .from(PostEntity , 'post')
  .leftJoinAndSelect('post.user','user')
  .orderBy('RANDOM()')
  .limit(1)
  .execute();
return array[0];

玩弄real / join函数和参数我只能得到:

  1. 仅1个属性“ userId”已添加到PostEntity对象
  2. “ userId”属性和所有其他用户属性在“ PostEntity”对象中添加了“ flat”
  3. 添加了“ userId”属性,而所有其他用户属性均以别名“ user_id”,“ user_firstName”等“ flat”添加。

因此,使用QueryBuilder,如何获得这样的帖子:

{
  id: 'e43c918c-55e1-4511-bce4-910fdd503548',
  text: 'this is some text',
  user: {
    id: '123456789',
    firstName: 'John',
    lastName: 'Doe',
  },
}

1 个答案:

答案 0 :(得分:0)

我在尝试进行原始查询时遇到了同样的问题,我找到的解决方案是使用 JSONB_BUILD_OBJECT()

https://www.postgresql.org/docs/9.5/functions-json.html

基本上你的查询看起来像这样:

select
  post.*,
  jsonb_build_object(
    'id', user."id",
    'firstName', user."firstName",
    'lastName', user."lastName"
  ) "user"
from...

我很想知道是否有使用 typeorm 子句的优雅方法,但是当我遇到这些 API 问题时,我通常只使用原始查询。