如何在Sequelize中用Op.iLike查询PostgreSQL的JSONB字段?
问题分析与解决
你的问题出在两个核心点上:
- 逻辑条件错误:原代码要求
title和body同时匹配搜索关键词,但你实际需要的应该是二者任一匹配 - JSONB字段查询语法错误:Sequelize无法直接通过嵌套对象的方式查询JSONB属性,必须用PostgreSQL JSONB专用的查询方式
正确的查询写法
方式1:简化JSON字段提取写法(推荐)
PostgreSQL支持->>操作符直接提取JSON属性为文本,Sequelize可以直接用字符串形式指定字段路径:
await this.customerNotificationRepository.findAndCountAll({ where: { [Op.or]: [ { 'notificationDescription->>title': { [Op.iLike]: `%${searchKey}%` } }, { 'notificationDescription->>body': { [Op.iLike]: `%${searchKey}%` } } ] } });
方式2:使用JSON提取函数写法
如果需要更灵活的JSON操作,可以用Sequelize内置的函数调用:
await this.customerNotificationRepository.findAndCountAll({ where: { [Op.or]: [ sequelize.where( sequelize.fn('jsonb_extract_path_text', sequelize.col('notificationDescription'), 'title'), { [Op.iLike]: `%${searchKey}%` } ), sequelize.where( sequelize.fn('jsonb_extract_path_text', sequelize.col('notificationDescription'), 'body'), { [Op.iLike]: `%${searchKey}%` } ) ] } });
关键注意事项
- 用
Op.or替代原逻辑中的隐含AND,确保title或body任一匹配就返回结果 - 必须通过
->>操作符或JSON提取函数访问嵌套属性,不能直接用对象嵌套写法 - 若担心SQL注入,可改用参数绑定形式:
sequelize.literal('%' || ? || '%', [searchKey]),Sequelize的Op.iLike也会自动处理基础的参数转义
内容的提问来源于stack exchange,提问作者Ishaq
相关产品推荐
相关产品推荐

