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

Prisma ORM如何对JSON字段根节点执行string_contains过滤?

解决Prisma中JSON字段全局内容搜索问题

你的问题出在Prisma的string_contains对JSON字段的处理逻辑上:它默认是匹配JSON结构内特定字符串字段的值,而非整个JSON的字符串形式,所以直接用nameTranslatableJson.string_contains无法生效。以下是两种可行的解决方案:

方案一:直接调用数据库JSON转字符串函数(快速实现)

根据你使用的数据库类型,通过Prisma的raw查询将JSON字段转为字符串后进行模糊匹配:

PostgreSQL 示例

this._prismaService.service.findMany({
  ...args,
  where: {
    OR: [
      Prisma.sql`jsonb_to_text("nameTranslatableJson") LIKE ${`%${filters.search}%`}`,
    ],
  },
});

MySQL 示例

this._prismaService.service.findMany({
  ...args,
  where: {
    OR: [
      Prisma.sql`JSON_STRINGIFY(\`nameTranslatableJson\`) LIKE ${`%${filters.search}%`}`,
    ],
  },
});

方案二:生成字符串列+索引(高性能方案)

如果需要频繁进行这类搜索,推荐在数据库中创建一个生成列,将JSON字段自动转为字符串并存储,同时创建索引提升查询效率:

  1. 执行SQL语句添加生成列和索引:
-- PostgreSQL
ALTER TABLE "Service" ADD COLUMN "nameTranslatableJsonStr" TEXT GENERATED ALWAYS AS (jsonb_to_text("nameTranslatableJson")) STORED;
CREATE INDEX "Service_nameTranslatableJsonStr_idx" ON "Service" USING GIN ("nameTranslatableJsonStr" gin_trgm_ops);

-- MySQL
ALTER TABLE `Service` ADD COLUMN `nameTranslatableJsonStr` TEXT GENERATED ALWAYS AS (JSON_STRINGIFY(`nameTranslatableJson`)) STORED;
CREATE FULLTEXT INDEX `Service_nameTranslatableJsonStr_idx` ON `Service`(`nameTranslatableJsonStr`);
  1. 更新Prisma Schema,添加生成列:
model Service {
  // 其他字段...
  nameTranslatableJson Json
  nameTranslatableJsonStr String @generated @db.Text
}
  1. 正常使用string_contains查询:
this._prismaService.service.findMany({
  ...args,
  where: {
    OR: [
      {
        nameTranslatableJsonStr: {
          string_contains: filters.search,
        },
      },
    ],
  },
});

内容的提问来源于stack exchange,提问作者Fabian VC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:05:20