gpt4 book ai didi

TypeORM - 使用带 leftJoinAndSelect 的 take/limit 没有按预期工作

转载 作者:行者123 更新时间:2023-12-05 07:26:25 25 4
gpt4 key购买 nike

我尝试通过 QueryBuilder 获取关系表,它工作正常,直到我尝试使用 skip/offset 和 take/limit。我期待这样的返回:

[
{
"id": 1, // order.id
"locations": [ ... ] array of locations with same order.id
},
{
"id": 2,
"locations": [ ... ]
},
{
"id": 3,
"locations": [ ... ]
}
]

order.entity.ts

@PrimaryGeneratedColumn({ name: 'id' })
public id!: number;

@OneToMany((type) => Location, (location) => location.order, {
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
})
public locations: Location[];

locations.entity.ts

@PrimaryGeneratedColumn({ name: 'id' })
public id!: number;

@ManyToOne((type) => Order, (order) => order.locations, {
nullable: false,
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
})
@JoinColumn({ name: 'order_id' })
public order: Order = null;

[查询 A] 我通过以下代码获得了所需的输出:(但不使用 skip/take,输出位于该问题的顶部)

const orders = getRepository(Order)
.createQueryBuilder('order')
.where('order.customer_id = :customer', { customer: user.id })
.leftJoinAndSelect('order.locations', 'location', 'location.order_id = order.order_id')
.getMany(); // output count is 35, output count with limit/take of 10 would be 10

[查询 B] 如果我添加 skip/offset 和 take/limit,它将如下所示:

const orders = getRepository(Order)
.createQueryBuilder('order')
.where('order.customer_id = :customer', { customer: user.id })
.leftJoinAndSelect('order.locations', 'location', 'location.order_id = order.order_id')
.skip(0)
.limit(10)
.getMany(); // output count is 5

但是在这里,输出是正确的,但是长度/计数是完全错误的。 查询 A 找到 35 个订单,总有 2 个位置。如果我从 Query A 中删除 leftJoinAndSelect 并添加 skip and take,那么它也会找到 35 个订单。但是 查询 B,限制/获取为 10,给我的输出计数为 5。它减半了输出!如果 limit/take 等于 8,则输出长度为 4。输出减半!显然,getMany 有一些神奇之处,所以我找到了 getRawMany,它可以使输出加倍。因为对于每个订单,有 2 个位置。那也不是我需要的。而且这个输出的结构也是错误的(如下所示)。 getManyRaw 没问题,但如果我将它与 skip/take 一起使用则不行,因为输出显然是错误的,因为我需要每个订单的所有位置。 Group By 在这里没有帮助,因为这样我每个订单只有 1 个位置。

getRawMany 的输出是这样的

[
{
"order_id": 1,
"locations_id": 100
},
{
"order_id": 1,
"locations_id": 101
},
{
"id": 2,
"locations_id": 102
},
{
"id": 2,
"locations_id": 103
},
{
"id": 3,
"locations_id": 104
},
{
"id": 3,
"locations_id": 105
}
]

正如我所说,在这里使用 skip/take 会给我一个错误的结果。我怎样才能达到我的预期输出?

最佳答案

希望我能得到您的问题,基本上您想要实现的是跳过并接受父订单,而不管它有多少个子位置。这是正确的吗?

如果我的理解是正确的,你可以使用这样的方法:

const orders = getRepository(Order) // use await if it inside async function
.createQueryBuilder('order')
.addSelect('@row_number := ' +
'CASE WHEN @parent_id <> location.order_id ' +
'THEN @row_number + 1 ' +
'ELSE @row_number END AS rn, ' +
'@parent_id := location.order_id'
)
.where('order.customer_id = :customer', { customer: user.id })
.leftJoinAndSelect('order.locations', 'location', 'location.order_id = order.order_id')
.innerJoin('(SELECT @row_number := 0)', 'init_row', '1 = 1')
.innerJoin('(SELECT @parent_id := 0)', 'init_id', '1 = 1')
.orderBy('location.order_id')
.having('rn <= 10')
.getMany(); // now output should be 10 in case u want to skip use rn > 10 AND rn <= 20 condition

关于TypeORM - 使用带 leftJoinAndSelect 的 take/limit 没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54338689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com