Prisma - 如何使用计数作为关系条件
Prisma - How to use count as a where condition with relation
我使用 nestjs
和 postgresql
以及 prisma
。我有 2 个 table 相关,我想创建一个 where 子句,以便在第二个 table 中的记录数小于 - 让我们说 - 3 时获取记录。更多详细信息;
这是我的架构
model User {
id String @id
someOtherFields String
outgoingPlayMateRequest PlayMateRequest[] @relation("userId")
incomingPlayMateRequest PlayMateRequest[] @relation("targetId")
}
model PlayMateRequest {
id Int @id
requestingUser User @relation(name: "userId", fields: [requestingUserId], references: [id], onDelete: Cascade)
targetUser User @relation(name: "targetId", fields: [targetUserId], references: [id], onDelete: Cascade)
requestingUserId String
targetUserId String
someOtherFields String
response String //accept-reject-block
}
这是我的带有 where 子句的代码(我通过删除不相关的部分来简化它)
const userId = 'testUser';
return await this.prismaService.user.findMany({
where: {
NOT: {
id: userId //don't fetch user him/herself
},
lang: 'EN',
}
});
我这里要加的条件英文是;
Don't select users with incomingPlayMateRequest relation, if there are
3 records in PlayMateRequest table with response = reject
AND
requestingUser = userId
但无论如何我找不到在 where 中使用 count
作为条件。如我所见,我只能得到关系计数。我如何使用 prisma
执行此操作?
在 Prisma 中没有直接的方法来执行这样的条件,但您可以使用以下解决方法:
- 对过滤条件进行
groupBy
查询。
- 使用
map
创建符合过滤条件的所有用户 ID 的 User.id
字段数组。
- 执行正常的
findMany
查询,但使用过滤后的用户 ID 数组添加额外的 notIn
条件。
这是整个事情的样子:
const userId = 'testUser';
// step 1
const dataForFilter = await prisma.playMateRequest.groupBy({
by: ['targetUserId'],
where: {
response: "reject",
requestingUserId: userId
},
having: {
targetUserId: {
_count: {
equals: 3
}
}
}
})
// step 2
let exclude_users = [userId]
exclude_users = exclude_users.concat(dataForFilter.map(item => item.targetUserId))
let result = await prisma.playMateRequest.user.findMany({
where: {
id: {
notIn: exclude_users
},
lang: "en"
}
});
我可能误解了您想实现的查询的具体细节,但我认为这应该为您提供一般的查询结构。根据需要调整 groupBy
查询以匹配您的确切条件。
我使用 nestjs
和 postgresql
以及 prisma
。我有 2 个 table 相关,我想创建一个 where 子句,以便在第二个 table 中的记录数小于 - 让我们说 - 3 时获取记录。更多详细信息;
这是我的架构
model User {
id String @id
someOtherFields String
outgoingPlayMateRequest PlayMateRequest[] @relation("userId")
incomingPlayMateRequest PlayMateRequest[] @relation("targetId")
}
model PlayMateRequest {
id Int @id
requestingUser User @relation(name: "userId", fields: [requestingUserId], references: [id], onDelete: Cascade)
targetUser User @relation(name: "targetId", fields: [targetUserId], references: [id], onDelete: Cascade)
requestingUserId String
targetUserId String
someOtherFields String
response String //accept-reject-block
}
这是我的带有 where 子句的代码(我通过删除不相关的部分来简化它)
const userId = 'testUser';
return await this.prismaService.user.findMany({
where: {
NOT: {
id: userId //don't fetch user him/herself
},
lang: 'EN',
}
});
我这里要加的条件英文是;
Don't select users with incomingPlayMateRequest relation, if there are 3 records in PlayMateRequest table with
response = reject
ANDrequestingUser = userId
但无论如何我找不到在 where 中使用 count
作为条件。如我所见,我只能得到关系计数。我如何使用 prisma
执行此操作?
在 Prisma 中没有直接的方法来执行这样的条件,但您可以使用以下解决方法:
- 对过滤条件进行
groupBy
查询。 - 使用
map
创建符合过滤条件的所有用户 ID 的User.id
字段数组。 - 执行正常的
findMany
查询,但使用过滤后的用户 ID 数组添加额外的notIn
条件。
这是整个事情的样子:
const userId = 'testUser';
// step 1
const dataForFilter = await prisma.playMateRequest.groupBy({
by: ['targetUserId'],
where: {
response: "reject",
requestingUserId: userId
},
having: {
targetUserId: {
_count: {
equals: 3
}
}
}
})
// step 2
let exclude_users = [userId]
exclude_users = exclude_users.concat(dataForFilter.map(item => item.targetUserId))
let result = await prisma.playMateRequest.user.findMany({
where: {
id: {
notIn: exclude_users
},
lang: "en"
}
});
我可能误解了您想实现的查询的具体细节,但我认为这应该为您提供一般的查询结构。根据需要调整 groupBy
查询以匹配您的确切条件。