简体   繁体   中英

TypeORM Query entity with jsonb column by json property

I have an entity which holds a json object called "stats". Stats has multiple properties which Id like to order my findAll method by.

I tried everything but I can not get the query to work using my attempts.

This is how I am trying to find all Collection entities ordered by the stats.one_day_volume property

The error I am getting with my last approach shown below is "missing FROM-clause entry for table "stats"

 const result = await getRepository(Collection) .createQueryBuilder('collection') .orderBy('collection.stats.one_day_volume', "DESC") .take(take) .skip(skip) .getMany();

This is the entity class

 @Entity() export class Collection { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column({nullable:true}) external_link: string; @Column({nullable:true}) description: string; @Column() slug: string; @Column({nullable:true}) image_url: string; @Column({nullable:true}) banner_image_url: string; @Column() dev_seller_fee_basis_points: string; @Column() safelist_request_status: string; @Column({nullable:true}) payout_address: string; @Column('jsonb') primary_asset_contracts: AssetContract[]; @Column("simple-json") traits: object; @Column("jsonb", {array:true, nullable:true}) payment_tokens: PaymentToken[]; @Column("simple-array", {nullable:true}) editors: string[]; @Column("jsonb") stats: CollectionStats; @Column({ type: 'timestamptz' }) created_date: Date; }

I was also looking for a way to orderBy on jsonb column

But there's an issue when you try to getMany with it.

So my workaround was to have it this way (use getRawMany instead of getMany):

const result = await getRepository(Collection)
  .createQueryBuilder('collection')
  .orderBy("collection.stats->>'one_day_volume'", "DESC")
  .take(take)
  .skip(skip)
  .getRawMany();

So apparently with getRawMany it's working well.

To get it as an entity you can try create it from repo like so:

    const repo = await getRepository(Collection);
    const resultAsEntities = repo.create(result);

But looks like there are sometimes this won't work as expected due to relations and other objects so you may try achieve it this way:

const resultIds = result.map(item => item.id);
const resultAsEntities = await getRepository(Collection).findByIds(resultIds);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM