'TypeORM: How to order by a relation field
I have a Singer entity and a related Song entity
Singer entity
export class Singer {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany( type => Song, Song => Song.user )
songs: Song[];
}
Song entity
export class Song {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne( type => Singer, Singer => Singer.songs )
singer: Singer;
}
I want to get all Songs ordered by Singer name
I searched the docs and GitHub issues but can't find an answer
How can I solve this? better without QueryBuilder
Solution 1:[1]
I don't think it is currently supported by typeorm without the query builder, there is currently a feature request open
With the QueryBuilder it is quite simple though:
connection.createQueryBuilder(Song, 'songs')
.leftJoinAndSelect('songs.singer', 'singer')
.orderBy('singer.name', 'ASC')
.getMany();
Solution 2:[2]
I had the same issue i tried to order by custom column but without query builder because i was using Repository, this is my solution :
let res = await this.trackingRepository.findAndCount({
where: [{ username : Like(`%${searchValue}%`) },
{ action : Like(`%${searchValue}%`) },
{ ip : Like(`%${searchValue}%`) }],
order: {
[sortField]: sortOrder === "descend" ? 'DESC' : 'ASC',
},
skip: (current - 1) * pageSize,
take: pageSize,
});
Solution 3:[3]
Try the default order on the entity model
https://github.com/typeorm/typeorm/blob/master/sample/sample30-default-order-by/entity/Post.ts
@Entity("sample30_post", {
orderBy: {
title: "ASC",
id: "DESC"
}
})
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
}
Solution 4:[4]
You do not have to use the query builder if you are willing to do the ordering in-memory. (Careful: This implies fetching all data sets first and then conduct the filtering on your node server).
For this, you can delegate the task to a library like lodash. This way, you could still use the EntityManager or a Repository to query the data.
// first fetch the song and include (=join) the
// singer by the foreign key "singer"
var queryResult = await this.entityManager.find(Song, {
relations: ['singer'],
});
// then use a library like lodash to do the ordering
const songsSortedBySinger = _.orderBy(queryResult, song => song.singer.name);
For further reading:
- The
relationsfind option is documented here. - lodash's orderBy is documented here.
Solution 5:[5]
This is supported as of TypeORM 0.3.0:
songRepository.find({
order: {
singer: {
name: "ASC"
}
}
})
Solution 6:[6]
You could do it with a workaround with entity hooks if the result is not too large:
@AfterLoad()
sortItems() {
if (this?.sortableItems?.length) {
this.sortableItems.sort((a, b) => a.weight - b.weight);
}
}
Solution 7:[7]
I think typeorm added support for this feature. In my codebase I use a syntax like this, and it orders the results based on the singer.name.
const queryResult = await this.songRepository.find(Song, {
relations: ['singer'],
order: {
'singer.name': 'ASC',
},
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Phillip Kigenyi |
| Solution 4 | |
| Solution 5 | Tamlyn |
| Solution 6 | |
| Solution 7 | Bart In T Veld |
