简体   繁体   English

Prisma - 如何使用计数作为关系条件

[英]Prisma - How to use count as a where condition with relation

I use nestjs and postgresql with prisma .我将nestjspostgresqlprisma一起使用。 I have 2 tables in relation, I want to create a where clause in order to fetch the records if count of the records in the second table is less than -let's say- 3. More details;我有 2 个相关的表,如果第二个表中的记录数小于 - 比方说 - 3,我想创建一个 where 子句以获取记录。更多细节;

Here is my schema这是我的架构

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
}

and here is my code with where clause (I am simplfying it by removing unrelevant parts)这是我的带有 where 子句的代码(我通过删除不相关的部分来简化它)

const userId = 'testUser';
return await this.prismaService.user.findMany({
    where: {
      NOT: {
        id: userId //don't fetch user him/herself
      },
      lang: 'EN',
    }
  });

The condition I want to add here in english is;我想在这里用英文添加的条件是;

Don't select users with incomingPlayMateRequest relation, if there are 3 records in PlayMateRequest table with response = reject AND requestingUser = userId不要 select 用户与incomingPlayMateRequest 关系,如果PlayMateRequest 表中有3 条记录response = rejectrequestingUser = userId

But I couldn't find anyway to use count as a condition in where.但是我无论如何都找不到使用count作为 where 的条件。 As I see I can only get the relations count.如我所见,我只能获得关系计数。 How can I do this with prisma ?我怎么能用prisma做到这一点?

There's no direct way to do a condition like this in Prisma, but here is a workaround you could use:在 Prisma 中没有直接的方法来执行这样的条件,但是您可以使用以下解决方法:

  1. Do a groupBy query for the filter condition.对过滤条件执行groupBy查询。
  2. Use a map to create array of User.id fields of all the user ids that match the filter condition.使用map创建与过滤条件匹配的所有用户 id 的User.id字段数组。
  3. Do the normal findMany query, but add an extra notIn condition with the array of filtered user ids.执行正常的findMany查询,但在过滤后的用户 ID 数组中添加一个额外的notIn条件。

Here is what the whole thing would look like:这是整个事情的样子:

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"
    }
    });

I might have misinterpreted the exact details of the query you want to achieve but I think this should give you the query structure in general.我可能误解了您想要实现的查询的确切细节,但我认为这应该为您提供一般的查询结构。 Tweak the groupBy query as necessary to match your exact condition.根据需要调整groupBy查询以匹配您的确切条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM