You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prisma同模型双向多对多关系查询优化方案咨询

优化Prisma同模型双向多对多关系的查询体验

针对你遇到的同模型双向多对多关系需要手动合并字段的问题,有三种更优的实现方式:

方案一:写入时创建双向关联,统一查询字段

在创建艺术家关联时,同时写入两条方向相反的中间表记录,这样查询时只需要调用一个字段就能获取所有相关艺术家:

写入逻辑示例

async function addRelatedArtists(artistId1, artistId2) {
  await prisma.relatedArtist.createMany({
    data: [
      { artistId: artistId1, relatedArtistId: artistId2 },
      { artistId: artistId2, relatedArtistId: artistId1 },
    ],
    skipDuplicates: true, // 避免重复创建关联
  })
}

查询示例

创建双向关联后,直接查询relatedArtists字段即可:

const artist = await prisma.artist.findUnique({
  where: { id: artistId },
  include: { relatedArtists: { include: { relatedArtist: true } } },
})

const relatedArtists = artist.relatedArtists.map(item => item.relatedArtist)

方案二:用Prisma客户端扩展自动合并字段

通过Prisma客户端的扩展功能,给Artist模型添加计算属性,自动合并两个方向的关联结果,无需手动处理:

扩展客户端配置

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient().$extends({
  result: {
    artist: {
      allRelatedArtists: {
        // 指定需要依赖的字段
        needs: { relatedArtists: true, artists: true },
        // 自动合并并去重
        compute(artist) {
          const combined = [
            ...artist.relatedArtists.map(ra => ra.relatedArtist),
            ...artist.artists.map(a => a.artist),
          ]
          // 去重避免重复关联
          return Array.from(new Map(combined.map(item => [item.id, item])).values())
        },
      },
    },
  },
})

使用示例

查询时直接获取合并后的字段:

const artist = await prisma.artist.findUnique({
  where: { id: artistId },
  include: {
    relatedArtists: { include: { relatedArtist: true } },
    artists: { include: { artist: true } },
  },
})

console.log(artist.allRelatedArtists) // 直接拿到所有相关艺术家

方案三:封装查询函数统一处理

如果不想修改模型或扩展客户端,可以封装一个查询函数,内部处理字段合并逻辑,对外提供统一接口:

封装函数示例

async function getArtistWithRelated(artistId) {
  const artist = await prisma.artist.findUnique({
    where: { id: artistId },
    include: {
      relatedArtists: { include: { relatedArtist: true } },
      artists: { include: { artist: true } },
    },
  })

  // 合并并去重
  const relatedArtists = Array.from(
    new Map([
      ...artist.relatedArtists.map(ra => [ra.relatedArtist.id, ra.relatedArtist]),
      ...artist.artists.map(a => [a.artist.id, a.artist]),
    ]).values()
  )

  return { ...artist, relatedArtists }
}

使用示例

const artist = await getArtistWithRelated(artistId)
console.log(artist.relatedArtists) // 统一字段返回结果

内容的提问来源于stack exchange,提问作者Andrew Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 04:45:08