So i've got a project on nestjs and using TypeORM. And my situation is i have a User which have One-to-May relation with UserSubscrption. Default find query added all subscriptions to User as it should be. So now i want to find one specific subscription, for example last added. So i build this query:
const query = this.createQueryBuilder("user")
.leftJoinAndSelect("user.settings", "settings")
.leftJoinAndSelect(
subQuery => {
return subQuery
.select()
.from(UserSubscription, "subscription")
.where("subscription.userId = :id AND subscription.isConfirmed = :isConfirmed", { id, isConfirmed: true })
.orderBy('"createdDate"', 'DESC')
.limit(1);
}, 'subscription', '"subscription"."userId" = "user"."id"')
.where('user.id = :id', { id });
const result = await query.getOne(); // await query.execute()
First, i try just execute the query and it works fine but all the data not structured
[
{
user_id: 1,
user_username: 'name',
...
settings_id: 1,
settings_ifOnline: true,
...
subscriptions_id: 1,
subscriptions_subscriptionId: 1,
...
}
]
So it's not good.
Then i try query.getOne() but it wont work as i want, it's lost all subscription data
User {
id: 1,
username: 'name',
...
settings: UserNotificationSettings {
id: 1,
ifOnline: true,
...
}
}
Also, i tried to add virtual field subscription to user entity and try to use leftJoinAndMapOne:
...
.leftJoinAndSelect("user.settings", "settings")
.leftJoinAndMapOne("user.subscription",
subQuery => {
return subQuery
.select()
.from(UserSubscription, "subscription")
.where("subscription.userId = :id AND subscription.isConfirmed = :isConfirmed", { id, isConfirmed: true })
.orderBy('"createdDate"', 'DESC')
.limit(1);
}, 'subscription', '"subscription"."userId" = "user"."id"')
...
But with no luck. In docs it's said that "Subqueries are supported in FROM, WHERE and JOIN expressions." but no example is provided. So, i have no idea how to handle this i belive pretty much simple query with TypeORM. Any suggestions? i'm kinda stuck with this. May be there is some better way than buildibg queries? Thanks.
User.entity
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
...
// subscription: UserSubscription;
@OneToMany(type => UserSubscription, subscriptions => subscriptions.user, { cascade:true })
subscriptions: UserSubscription[];
@OneToOne(type => UserNotificationSettings, settings => settings.user, { cascade:true })
settings: UserNotificationSettings;
}
UserSubscription.entity
export class UserSubscription extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@OneToOne(type => Subscription)
@JoinColumn()
subscription: Subscription
@Column()
subscriptionId: number
@ManyToOne(type => User, user => user.subscriptions)
user: User
@Column({type: 'integer'})
userId: number
@Column({ type: 'boolean', default: false })
isConfirmed: boolean
...
}