我有以下不相关的TypeORM实体(由于各种原因,我不能在它们上使用一个或多个关系(:
@Entity()
export class Book {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
@Entity()
export class BookCategory {
@PrimaryGeneratedColumn()
id: number;
@Column()
bookId: number;
@Column()
name: string;
}
使用一本书、两个分配的类别和以下查询:
const query = this.bookRepository
.createQueryBuilder('book')
.leftJoinAndSelect(BookCategory, 'category', 'book.id = category.bookId');
return query.execute();
我得到以下响应:
[
{
"book_id": 1,
"book_name": "Lorem Ipsum",
"category_id": 1,
"category_name": "non-fiction"
},
{
"book_id": 1,
"book_name": "Lorem Ipsum",
"category_id": 2,
"category_name": "documentary"
}
]
如您所见,我得到了 2 个对象。有什么方法可以通过TypeORM查询获得以下内容吗?
[
{
"id": 1,
"name": "Lorem Ipsum",
"categories": ["non-fiction", "documentary"]
}
]
即我正在尝试将查询结果绑定到虚拟属性categories
。这可能吗?
我认为TypeORM本身不可能做到这一点,但是您可以使用map()
函数通过以下方式实现它:
const categories: string[] = query.execute().map((book) => book.category_name );
const book = {id: bookArray[0].book_id, name: bookArray[0].book_name, categories};
//OUTPUT:
{
id: 1,
name: 'Lorem Ipsum',
categories: [ 'non-fiction', 'documentary' ]
}
这不是一种干净的方法,但是由于您通过其ID请求单个书籍,因此您将确保每个数组对象中的book_id
和book_name
属性始终相同。
TypeORM 还建议使用getMany()
或getOne()
而不是执行查询:
const books: Book[] = await this.bookRepository
.createQueryBuilder('book')
.leftJoinAndSelect(BookCategory, 'category', 'book.id = category.bookId')
.getMany();
我不知道他怎么做queryBuilder
,sql
它看起来像这样。
SELECT
book.id as book_id,
book.name as book_name,
array_remove(array_agg(bc.name), NULL) as categories
FROM book
LEFT JOIN book_category bc ON bc."bookId"=book.id
GROUP BY book.id
我可能犯了一个错误,因为我没有自己检查它。但它应该是这样的。
执行时,你应该得到一个表
book_id | book_name | category |
---|---|---|
本书名称1 | ["猫名", "猫名2"] | |
2 | ["猫名"] |