Prisma 上与 Self 的一对多关系

Posted

技术标签:

【中文标题】Prisma 上与 Self 的一对多关系【英文标题】:One to many relationships with Self on Prisma 【发布时间】:2021-10-28 01:03:41 【问题描述】:

我正在尝试使用 Prisma 实现一个类似于 tinder 的简单应用程序,用户可以左右滑动来喜欢或不喜欢另一个用户,之后,我就能够获取匹配项和候选人。匹配的都是喜欢我的用户,候选的都是除了我自己、我的匹配、我不喜欢的用户和不喜欢我的用途之外的所有用户。

我让它创建了一个用户模型、一个喜欢模型和一个不喜欢模型

model User 
  id            String     @id
  username      String     @default(value: "")
  age           Int        @default(value: 0)
  bio           String     @default(value: "") @db.VarChar(1000)


model Likes 
  id          Int    @id @default(autoincrement())
  userId      String
  likedUserId String


model Dislikes 
  id             Int    @id @default(autoincrement())
  userId         String
  dislikedUserId String

并创建几个相当复杂的 SQL 语句并使用 queryRaw 运行它们

它确实有效,但我觉得我没有正确使用 Prisma,我只是将 SQL 转换为 Prisma。所以我决定改变我的模型如下

model User 
  id            String     @id
  username      String     @default(value: "")
  age           Int        @default(value: 0)
  bio           String     @default(value: "") @db.VarChar(1000)
  liked         User[]     @relation("LikedUserToUser")
  disliked      User[]     @relation("DislikedUserToUser")

我的 IDE 提示我添加相反的关系或运行 prisma format 这样做之后,我最终得到了这样的结果

model User 
  id           String     @id
  username     String     @default(value: "")
  age          Int        @default(value: 0)
  bio          String     @default(value: "") @db.VarChar(1000)
  liked        User[]     @relation("LikedUserToUser")
  disliked     User[]     @relation("DislikedUserToUser")
  userToLike    User?      @relation("LikedUserToUser", fields: [userId], references: [id])
  userToDislike User?      @relation("DislikedUserToUser", fields: [userId], references: [id])
  userId       String?

现在,它似乎工作得很好,我可以“喜欢”一个用户

const user = await prisma.user.update(
    where:  id: '1' ,
    data: 
      liked: 
        connect:  id: '2' ,
      ,
    ,
  )

当我查询用户“1”时,包括我得到的喜欢


  id: '1',
  username: 'Cheryl',
  age: 36,
  bio: 'ornare, libero at auctor ullamcorper',
  userId: null,
  liked: [
    
      id: '2',
      username: 'Daphne',
      age: 57,
      bio: 'at sem molestie sodales',
      userId: '1'
    
  ]

我的问题是我不知道如何运行上述更复杂的查询、匹配项和候选人。有什么想法吗?

【问题讨论】:

【参考方案1】:

你的架构应该是这样的:

model User 
  id             String  @id
  username       String  @default(value: "")
  age            Int     @default(value: 0)
  bio            String  @default(value: "")
  liked          User[]  @relation("likedUsers")
  disliked       User[]  @relation("dislikedUsers")
  likedUser      User?   @relation("likedUsers", fields: [likedUserId], references: [id])
  likedUserId    String?
  dislikedUser   User?   @relation("dislikedUsers", fields: [dislikedUserId], references: [id])
  dislikedUserId String? @map("userId")

然后您可以运行这样的查询(用户 1 喜欢用户 2):

const user = await prisma.user.update(
    where:  id: '1' ,
    data: 
      liked: 
        connect:  id: '2' ,
      ,
    ,
)

使用nested reads 也可以轻松获取用户 1 喜欢的用户:

const user = await prisma.user.findUnique(
    where:  id: '1' ,
    include:  liked: true 
)

【讨论】:

这正是我试图做的,但我得到了Error validating field 'liked' in model 'User': The relation field 'liked' on Model 'User' is missing an opposite relation field on the model 'User'. Either run 'prisma format' or add it manually. 的查询与我的完全一样并且完美地工作 这很好用。 @relation 中的名称应该相同,然后您就不会收到此错误。 这样做错误消失了,但行为很奇怪:如果我为 user1 运行上面的查询来喜欢 use2,则用户 2 被添加到用户 1 的喜欢中,但用户 1 也被添加到用户 2不喜欢! 在这种情况下,您需要为喜欢和不喜欢添加单独的关系。在我的答案中编辑架构。查询将保持不变。

以上是关于Prisma 上与 Self 的一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

Prisma 插入关系一对多

Prisma 可以从关系表中创建一对多关系吗?

prisma 模式中的一对多自关系

与附加字段的一对多关系

在 Django 中使用“Self”关键字和一对多关系调用属性

获取核心数据中一对多关系的计数