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

如何使用TypeORM匹配JSON字段内键值对并更新数据

解决方案:NestJS + TypeORM 更新PostgreSQL JSON字段匹配的记录

1. 确保实体字段定义正确

首先确认travel_bookings实体的booking_response字段使用PostgreSQL的jsonb类型(比json更适合查询和索引):

import { Entity, Column, PrimaryGeneratedColumn, Index } from 'typeorm';

@Entity('travel_bookings')
// 可选:给JSON字段内的id创建索引优化查询性能
@Index('idx_response_id', { expression: '(booking_response->>\'id\')' })
export class TravelBookings {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('jsonb')
  booking_response: Record<string, any>;

  @Column()
  status: string;

  // 其他业务字段...
}

2. 实现更新函数的两种方式

方式一:使用QueryBuilder(推荐,语法直观且灵活)

直接通过PostgreSQL的JSON操作符->>匹配booking_response内的id值,然后更新status字段:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TravelBookings } from './travel-bookings.entity';

@Injectable()
export class TravelBookingsService {
  constructor(
    @InjectRepository(TravelBookings)
    private readonly repo: Repository<TravelBookings>,
  ) {}

  async cancelByResponseId(targetId: string | number): Promise<void> {
    // 如果targetId是数字,需要转换类型:(booking_response->>'id')::int = :targetId
    const whereClause = typeof targetId === 'number' 
      ? '(booking_response->>\'id\')::int = :targetId' 
      : 'booking_response->>\'id\' = :targetId';

    await this.repo
      .createQueryBuilder()
      .update(TravelBookings)
      .set({ status: 'Cancelled' })
      .where(whereClause, { targetId })
      .execute();
  }
}

方式二:使用Repository的update方法配合Raw查询

通过TypeORM的Raw函数生成原生SQL条件:

async cancelByResponseId(targetId: string | number): Promise<void> {
  const condition = typeof targetId === 'number'
    ? Raw(alias => `(${alias}->>'id')::int = :targetId`, { targetId })
    : Raw(alias => `${alias}->>'id' = :targetId`, { targetId });

  await this.repo.update(
    { booking_response: condition },
    { status: 'Cancelled' },
  );
}

关键说明

  • PostgreSQL的->>操作符用于提取JSON字段的文本值,->则返回JSON类型值,根据你的id类型(字符串/数字)选择合适的写法。
  • 如果id是嵌套在JSON的深层结构(比如booking_response.data.id),只需调整路径:booking_response->'data'->>'id'。
  • 建议给booking_response->>'id'创建索引,避免大数据量下的全表扫描。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:10:13