TypeORM:如何按关系字段排序
TypeORM: How to order by a relation field
我有一个 Singer
实体和一个相关的 Song
实体
Singer
实体
export class Singer {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany( type => Song, Song => Song.user )
songs: Song[];
}
Song
实体
export class Song {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne( type => Singer, Singer => Singer.songs )
singer: Singer;
}
我想按 Singer
姓名
订购所有 Songs
我搜索了文档和 GitHub 问题,但找不到答案
我该如何解决这个问题?没有 QueryBuilder
会更好
我认为没有查询生成器的 typeorm 目前不支持它,目前有一个 feature request 打开
虽然使用 QueryBuilder 非常简单:
connection.createQueryBuilder(Song, 'songs')
.leftJoinAndSelect('songs.singer', 'singer')
.orderBy('singer.name', 'ASC')
.getMany();
如果您愿意在内存中进行排序,则不必使用查询生成器。 (注意:这意味着先获取所有数据集,然后在您的节点服务器上进行过滤)。
为此,您可以将任务委托给像 lodash 这样的库。这样,您仍然可以使用 EntityManager
或 Repository
来查询数据。
// 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);
进一步阅读:
relations
查找选项是 documented here。
- lodash 的 orderBy 是 documented here.
当您使用存储库时:
var queryResult = await this.youRepository.find(Song, {
relations: ['singer'],
order: {
name: 'ASC',
},
});
如果结果不是太大,您可以使用实体挂钩的变通方法来实现:
@AfterLoad()
sortItems() {
if (this?.sortableItems?.length) {
this.sortableItems.sort((a, b) => a.weight - b.weight);
}
}
我遇到了同样的问题,我尝试按自定义列排序但没有查询生成器,因为我使用的是存储库,这是我的解决方案:
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,
});
我认为 typeorm 添加了对此功能的支持。在我的代码库中,我使用了这样的语法,它根据 singer.name
.
对结果进行排序
const queryResult = await this.songRepository.find(Song, {
relations: ['singer'],
order: {
'singer.name': 'ASC',
},
});
在实体模型上尝试默认顺序
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;
}
从 TypeORM 0.3.0 开始支持:
songRepository.find({
order: {
singer: {
name: "ASC"
}
}
})
我有一个 Singer
实体和一个相关的 Song
实体
Singer
实体
export class Singer {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany( type => Song, Song => Song.user )
songs: Song[];
}
Song
实体
export class Song {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne( type => Singer, Singer => Singer.songs )
singer: Singer;
}
我想按 Singer
姓名
Songs
我搜索了文档和 GitHub 问题,但找不到答案
我该如何解决这个问题?没有 QueryBuilder
我认为没有查询生成器的 typeorm 目前不支持它,目前有一个 feature request 打开
虽然使用 QueryBuilder 非常简单:
connection.createQueryBuilder(Song, 'songs')
.leftJoinAndSelect('songs.singer', 'singer')
.orderBy('singer.name', 'ASC')
.getMany();
如果您愿意在内存中进行排序,则不必使用查询生成器。 (注意:这意味着先获取所有数据集,然后在您的节点服务器上进行过滤)。
为此,您可以将任务委托给像 lodash 这样的库。这样,您仍然可以使用 EntityManager
或 Repository
来查询数据。
// 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);
进一步阅读:
relations
查找选项是 documented here。- lodash 的 orderBy 是 documented here.
当您使用存储库时:
var queryResult = await this.youRepository.find(Song, {
relations: ['singer'],
order: {
name: 'ASC',
},
});
如果结果不是太大,您可以使用实体挂钩的变通方法来实现:
@AfterLoad()
sortItems() {
if (this?.sortableItems?.length) {
this.sortableItems.sort((a, b) => a.weight - b.weight);
}
}
我遇到了同样的问题,我尝试按自定义列排序但没有查询生成器,因为我使用的是存储库,这是我的解决方案:
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,
});
我认为 typeorm 添加了对此功能的支持。在我的代码库中,我使用了这样的语法,它根据 singer.name
.
const queryResult = await this.songRepository.find(Song, {
relations: ['singer'],
order: {
'singer.name': 'ASC',
},
});
在实体模型上尝试默认顺序
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;
}
从 TypeORM 0.3.0 开始支持:
songRepository.find({
order: {
singer: {
name: "ASC"
}
}
})