Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select only single/multiple fields from joined entity in Typeorm

accord to TypeOrm doc: https://github.com/typeorm/typeorm/blob/master/docs/select-query-builder.md#joining-relations

We can query the joined entity's field that will populate all its field into the response. I am not sure how to restrict only to few selected fields(single/multiple), I tried adding 'select([])' but it is not working in the generated SQL query I can see it is querying all the fields.

code:

import {Entity, PrimaryGeneratedColumn, Column, OneToMany} from "typeorm";
import {Photo} from "./Photo";

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    name: string;

    @OneToMany(type => Photo, photo => photo.user)
    photos: Photo[];
}
import {Entity, PrimaryGeneratedColumn, Column, ManyToOne} from "typeorm";
import {User} from "./User";

@Entity()
export class Photo {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    url: string;

    @Column()
    alt: string;

    @ManyToOne(type => User, user => user.photos)
    user: User;
}

and on the code:

const user = await createQueryBuilder("user")
    .leftJoinAndSelect("user.photos", "photo")
    .where("user.name = :name", { name: "Timber" })
    .getOne();

The above code gives the output as -

{
    id: 1,
    name: "Timber",
    photos: [{
        id: 1,
        url: "me-with-chakram.jpg",
        alt: "Me With Chakram"
    }, {
        id: 2,
        url: "me-with-trees.jpg",
        alt: "Me With Trees"
    }]
}

Is there a way I can query only 'url' and 'alt' so the output will look something like this -

{
    id: 1,
    name: "Timber",
    photos: [{
        url: "me-with-chakram.jpg",
        alt: "Me With Chakram"
    }, {
        url: "me-with-trees.jpg",
        alt: "Me With Trees"
    }]
}
like image 711
Dev AKS Avatar asked Oct 08 '20 10:10

Dev AKS


2 Answers

const user = await createQueryBuilder("user")
    .leftJoinAndSelect("user.photos", "photo")
    .select(['user', 'photo.url', 'photo.alt'])
    .where("user.name = :name", { name: "Timber" })
    .getOne();

or

const user = await createQueryBuilder("user")
    .leftJoinAndSelect("user.photos", "photo")
    .addSelect(['photo.url', 'photo.alt'])
    .where("user.name = :name", { name: "Timber" })
    .getOne();

(not sure about the second one)

like image 115
Art Olshansky Avatar answered Oct 16 '22 10:10

Art Olshansky


The first answer given by Art Olshansky is right (the second one doesn't), so, you must stand "the base" entity but, if you don't need all/any user fields you can just apply

const user = await createQueryBuilder("user")
    .leftJoinAndSelect("user.photos", "photo")
    .select(['user.id', 'photo.url', 'photo.alt'])
    .where("user.name = :name", { name: "Timber" })
    .getOne();
like image 2
Jhon Zambrano Avatar answered Oct 16 '22 09:10

Jhon Zambrano