讲师中心 微信公众号
AI工具推荐 视频效率加速

PostgreSQL中查询JSON数组内指定字符串的高效教程

千辰小哥_4852

千辰小哥_4852

发布时间:2025-11-26 20:13:00

|

607人浏览过

|

来源于php中文网

原创

PostgreSQL中查询JSON数组内指定字符串的高效教程

本文旨在指导用户如何在postgresql数据库中,针对存储json数组的列进行高效且精确的查询。我们将重点介绍如何利用postgresql的json函数和操作符,从json数组的每个对象中提取特定键的值,并进行模糊字符串匹配,从而避免对整个json文本进行低效且可能出错的全局搜索。

1. 理解JSON数组查询的挑战

在PostgreSQL中,当数据库列存储JSON类型的数据,尤其是包含对象数组时,直接查询其中的特定内容会面临挑战。例如,一个名为 interval_note 的JSON列可能包含如下结构的数据:

[
  {"text":"bbb","userID":"U001","time":16704,"showInReport":true},
  {"text":"bb","userID":"U001","time":167047,"showInReport":true},
  {"text":"abc","userID":"U002","time":167048,"showInReport":false}
]

如果目标是查找 text 键中包含特定子字符串(如 'bb')的记录,直接将整个JSON列转换为文本并使用 LIKE 操作符(例如 rr.interval_note::text LIKE '%bb%')是不可靠的。这种方法会搜索JSON字符串中的任何位置,可能匹配到 userID 或其他字段中的 'bb',甚至匹配到JSON结构本身的字符,导致结果不准确且效率低下。我们需要一种能够深入JSON结构内部,精确提取所需字段并进行匹配的方法。

2. PostgreSQL JSONB数据类型与核心函数

PostgreSQL提供了强大的 JSON 和 JSONB 数据类型,以及一系列用于操作它们的函数和操作符。JSONB(二进制JSON)通常是首选,因为它以二进制格式存储数据,支持索引,并且在查询和处理时通常比 JSON 类型更高效。

对于查询JSON数组,以下函数和操作符至关重要:

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载
  • jsonb_array_elements(jsonb): 这个函数将一个JSONB数组展开,将其中的每个元素作为单独的JSONB对象返回。这对于遍历数组中的每个项进行处理非常有用。
  • -> (JSONB对象字段提取): 用于从JSONB对象中提取一个字段,返回结果仍为JSONB类型。
  • ->> (JSONB对象字段提取为文本): 用于从JSONB对象中提取一个字段,并将其值作为文本(TEXT)类型返回。这在进行字符串比较时非常有用。

3. 高效查询JSON数组的解决方案

要精确查找JSON数组中特定键(例如 text)的值包含特定字符串(例如 'bb')的记录,我们可以结合使用 jsonb_array_elements 函数和 CROSS JOIN LATERAL。

3.1 解决方案示例

假设我们的JSON数据存储在 cyto_record_results 表的 interval_note 列中,并且该列是 JSONB 类型(如果它是 JSON 类型,建议先转换为 JSONB 或使用 json_array_elements)。

SELECT DISTINCT r.workflowid
FROM cyto_records r
JOIN cyto_record_results rr ON r.recordid = rr.recordid
CROSS JOIN LATERAL jsonb_array_elements(rr.interval_note) AS note_element
WHERE note_element->>'text' LIKE '%bb%';

3.2 代码解析

  • FROM cyto_records r JOIN cyto_record_results rr ON r.recordid = rr.recordid: 这部分是标准的表连接,用于将 cyto_records 表和 cyto_record_results 表关联起来,以便获取 workflowid 和 interval_note 列。
  • CROSS JOIN LATERAL jsonb_array_elements(rr.interval_note) AS note_element:
    • jsonb_array_elements(rr.interval_note): 这个函数是核心。它接收 rr.interval_note 列中的JSONB数组,并将其中的每个元素(即每个 {"text":"bbb", ...} 这样的JSON对象)作为一行返回。
    • CROSS JOIN LATERAL: LATERAL 关键字允许 jsonb_array_elements 函数对 cyto_record_results 表的每一行独立执行。这意味着对于 rr 表中的每一条记录,如果其 interval_note 列是一个包含N个元素的数组,那么 jsonb_array_elements 就会生成N行,每行包含一个数组元素。这些生成的行会与原始的 rr 行进行交叉连接。最终,note_element 别名代表了从数组中解构出来的每一个独立的JSON对象。
  • WHERE note_element->>'text' LIKE '%bb%':
    • note_element->>'text': 从 note_element(即数组中的每个独立JSON对象)中提取 text 键的值。->> 操作符确保提取的值是 TEXT 类型,这对于后续的字符串匹配至关重要。
    • LIKE '%bb%': 对提取出的 text 值进行模糊匹配,查找任何包含子字符串 'bb' 的值。
  • SELECT DISTINCT r.workflowid: 由于一个 workflowid 可能对应多条 interval_note 记录,且一条 interval_note 记录中的JSON数组可能包含多个匹配的元素,为了避免重复,我们使用 DISTINCT 来获取唯一的 workflowid。

4. 注意事项与最佳实践

  • JSON vs. JSONB: 强烈推荐使用 JSONB 类型存储JSON数据。JSONB 提供了更快的处理速度、更小的存储空间(通常)以及对索引的支持。如果你的列当前是 JSON 类型,可以考虑将其更改为 JSONB,或在查询时显式地进行类型转换:jsonb_array_elements(rr.interval_note::jsonb).
  • 性能优化:GIN索引: 对于频繁查询JSONB列内部数据的场景,创建 GIN (Generalized Inverted Index) 索引可以显著提高查询性能。
    • 索引整个JSONB列: CREATE INDEX idx_interval_note_gin ON cyto_record_results USING GIN (interval_note); 这种索引可以加速对整个JSONB文档的 @> (contains) 或 ? (key exists) 操作。
    • 索引特定路径: 如果你只关心 text 字段的查询,可以创建表达式索引: CREATE INDEX idx_interval_note_text_gin ON cyto_record_results USING GIN ((interval_note jsonb_path_ops)); 或者更具体地,如果你的PostgreSQL版本支持,可以为展开的元素创建索引(但这通常更复杂,直接在 jsonb 列上创建 GIN 索引并依赖查询优化器是更常见的做法)。
  • 键不存在的处理: 如果 note_element 中不包含 text 键,note_element->>'text' 将返回 NULL。LIKE 操作符对 NULL 值不起作用,因此这些行不会被匹配。这通常是期望的行为。
  • 数据量与性能: 对于包含大量元素(例如成千上万个)的JSON数组,jsonb_array_elements 的展开操作可能会消耗较多的内存和CPU资源。在设计数据模型时应权衡JSON的嵌套深度和数组大小。

5. 总结

通过利用PostgreSQL的 jsonb_array_elements 函数结合 CROSS JOIN LATERAL,我们可以有效地解构JSON数组,精确地访问和过滤其中的数据。这种方法不仅提供了准确的查询结果,而且通过选择 JSONB 类型和适当的索引,还能确保在处理大量JSON数据时的良好性能,远优于对整个JSON文本进行模糊匹配的传统方式。

热门AI工具

更多
火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2155

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3342

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1116

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3839

2025.09.10

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3031

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

554

2025.10.31

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

522

2026.02.12

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21.1万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn