news 2026/9/18 5:45:34

StarRocks JSON 函数与操作符全景:构造函数、查询处理函数、JSON 操作符与路径表达式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
StarRocks JSON 函数与操作符全景:构造函数、查询处理函数、JSON 操作符与路径表达式

StarRocks JSON 函数与操作符全景:构造函数、查询处理函数、JSON 操作符与路径表达式

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

本文以 StarRocks 官方文档中「JSON functions and operators overview」页面为主体,系统梳理 StarRocks 对 JSON 数据的三类处理能力:JSON 构造函数(json_objectjson_arrayparse_json)、JSON 查询/处理函数(箭头函数->castget_json_*json_queryjson_removejson_eachjson_existsjson_keysjson_lengthjson_string)、JSON 比较操作符(<<=>,>==!=),以及 StarRocks 方言下的 JSON 路径表达式语法($.[n][*][start:end])。读完本文,你可以直接掌握如何在 StarRocks 中构造、查询、修改和比较 JSON 数据,并能结合 BE 源码(如 json_functions.h 与 jsonpath.h)理解这些函数在查询引擎中的实现方式,进而在日志分析、用户画像等半结构化数据场景写出可运行的 JSON 查询。

一、总览:三类 JSON 能力

StarRocks 文档将 JSON 能力划分为三组:

  1. JSON 构造函数(JSON constructor functions):用于从零构造 JSON 对象、JSON 数组,或把字符串解析为 JSON 值;
  2. JSON 查询函数与处理函数(JSON query functions and processing functions):用于查询 JSON 内部元素(按路径定位)、在 JSON 与 SQL 类型之间转换、删除/展开/校验 JSON 数据;
  3. JSON 操作符与路径表达式(JSON operators and path expressions):用于比较两个 JSON 值、用路径字符串定位 JSON 对象中的元素。

官方文档还特别提示:可以用生成列(generated columns)来加速对 JSON 列的重复查询——即把常用路径提前物化成列,避免每行重复解析。

二、JSON 构造函数

JSON 构造函数用于构造 JSON 对象和 JSON 数组等 JSON 数据,包含三个函数:

函数说明示例返回值
json_object将一组键值对转换为由这些键值对组成的 JSON 对象,键值对按键的字典序排序SELECT JSON_OBJECT('Daniel Smith', 26, 'Lily Smith', 25);{"Daniel Smith": 26, "Lily Smith": 25}
json_array将 SQL 数组的每个元素转换为 JSON 值,返回由这些值组成的 JSON 数组SELECT JSON_ARRAY(1, 2, 3);[1,2,3]
parse_json将字符串转换为 JSON 值SELECT PARSE_JSON('{"a": 1}');{"a": 1}

2.1 json_object:由键值对构造对象

语法为json_object(key, value, ...)。参数约束如下(摘自 json_object 文档):

  • key:JSON 对象的键,仅支持 VARCHAR 类型;
  • value:JSON 对象的值,支持NULL以及 STRING、VARCHAR、CHAR、JSON、TINYINT、SMALLINT、INT、BIGINT、LARGEINT、DOUBLE、FLOAT、BOOLEAN。

返回值是一个 JSON 对象;如果键值总数为奇数,最后一个字段会被填充NULL。典型示例:

-- 由不同类型的值构造对象 SELECT json_object('name', 'starrocks', 'active', true, 'published', 2020); -- 返回 {"active": true, "name": "starrocks", "published": 2020} -- 嵌套构造 SELECT json_object('k1', 1, 'k2', json_object('k2', 2), 'k3', json_array(4, 5)); -- 返回 {"k1": 1, "k2": {"k2": 2}, "k3": [4, 5]} -- 空对象 SELECT json_object(); -- 返回 {}

2.2 parse_json:把字符串变成 JSON 值

语法为parse_json(string_expr),参数只支持 STRING/VARCHAR/CHAR 类型。返回值是一个 JSON 值;如果字符串无法解析为标准 JSON 值,返回NULL(例如{star: "rocks"}中键未加双引号时)。要点示例:

SELECT parse_json('1'); -- 标量 "1" SELECT parse_json('[1,2,3]'); -- JSON 数组 [1, 2, 3] SELECT parse_json('{"star": "rocks"}'); -- JSON 对象 {"star": "rocks"} SELECT parse_json('null'); -- JSON 字面量 null SELECT parse_json('{star: "rocks"}'); -- 非法 JSON,返回 NULL

一个容易踩坑的细节:当 JSON 键本身包含.时,路径中必须转义或用引号包裹整个键,例如:

SELECT parse_json('{"b":4, "a.1": "1"}')->"a\\.1"; -- 返回 "1" SELECT parse_json('{"b":4, "a.1": "1"}')->'"a.1"'; -- 返回 "1"

2.3 源码视角:这些函数在 BE 中如何落地

从源码结构看,上述构造函数都在 BE 端以向量化函数实现。be/src/exprs/json_functions.h 中的JsonFunctions类声明了parse_jsonjson_objectjson_object_emptyjson_arrayjson_array_emptyDEFINE_VECTORIZED_FN函数——参数与返回类型分别对应BinaryColumn(字符串)与JsonColumn(JSON 列),说明 StarRocks 对 JSON 采用了列式(Column)存储与向量化求值,而非逐行标量计算。值得注意的是,BE 源码中还存在json_setjson_prettyjson_containsto_jsonis_json_scalar等总览表之外、但仓库文档目录下已收录的函数,可见实际函数面比总览页更宽。

三、JSON 查询函数与处理函数

用于查询和处理 JSON 数据。例如,可以用路径表达式在 JSON 对象中定位某个元素。总览页收录的函数如下:

函数说明示例返回值
箭头函数查询 JSON 对象中可通过路径表达式定位的元素SELECT parse_json('{"a": {"b": 1}}') -> '$.a.b';1
cast在 JSON 数据类型与 SQL 数据类型之间转换SELECT CAST(1 AS JSON);1
get_json_double解析 JSON 字符串并从指定路径取出浮点值SELECT get_json_double('{"k1":1.3, "k2":"2"}', "$.k1");1.3
get_json_int解析 JSON 字符串并从指定路径取出整数值SELECT get_json_int('{"k1":1, "k2":"2"}', "$.k1");1
get_json_string解析 JSON 字符串并从指定路径取出字符串SELECT get_json_string('{"k1":"v1", "k2":"v2"}', "$.k1");v1
json_query查询 JSON 对象中可通过路径表达式定位的元素的值SELECT JSON_QUERY('{"a": 1}', '$.a');1
json_remove从一个或多个指定 JSON 路径处删除 JSON 文档中的数据SELECT JSON_REMOVE('{"a": 1, "b": [10, 20, 30]}', '$.a', '$.b[1]');{"b": [10, 30]}
json_each将 JSON 对象的顶层元素展开为键值对SELECT * FROM tj_test, LATERAL JSON_EACH(j);见 json_each 示例图
json_exists检查 JSON 对象中是否包含可通过路径定位的元素,存在返回 1,否则返回 0SELECT JSON_EXISTS('{"a": 1}', '$.a');1
json_keys以 JSON 数组形式返回 JSON 对象的顶层键;若指定路径则返回该路径下的顶层键SELECT JSON_KEYS('{"a": 1, "b": 2, "c": 3}');["a", "b", "c"]
json_length返回 JSON 文档的长度SELECT json_length('{"Name": "Alice"}');1
json_string将 JSON 对象转换为 JSON 字符串SELECT json_string(parse_json('{"Name": "Alice"}'));{"Name": "Alice"}

下面对其中最具代表性的几个函数展开讲解。

3.1 箭头函数->与 json_query:按路径取值

箭头函数 的语法是json_object_expr -> json_path,它比 json_query 函数json_query(json_object_expr, json_path)更紧凑易用。两者第一个参数都可以是 JSON 列,或PARSE_JSON等构造函数产生的 JSON 对象;第二个参数是表示路径的字符串。返回值都是 JSON 值,若元素不存在则返回 SQL 的NULL

-- 基本用法 SELECT parse_json('{"a": {"b": 1}}') -> '$.a.b'; -- 返回 1 -- 嵌套箭头函数:内层结果继续定位 SELECT parse_json('{"a": {"b": 1}}')->'a'->'b'; -- 返回 1 -- 路径可省略根节点 $ SELECT parse_json('{"a": "b"}') -> 'a'; -- 返回 "b"

json_query的行为完全对应,且数组索引越界时同样返回NULL

SELECT json_query(PARSE_JSON('{"a": {"b": 1}}'), '$.a.b'); -- 1 SELECT json_query(PARSE_JSON('{"a": {"b": 1}}'), '$.a.c'); -- NULL SELECT json_query(PARSE_JSON('{"a": [1,2,3]}'), '$.a[2]'); -- 3 SELECT json_query(PARSE_JSON('{"a": [1,2,3]}'), '$.a[3]'); -- NULL

从源码结构看,BE 端 json_functions.h 中json_query被声明为接受[JsonColumn, BinaryColumn]、返回 JSON 列的向量化函数,并存在get_native_json_*系列函数(如get_native_json_intget_native_json_string),即对原生 JSON 列取标量值时会走类型化的快路径,避免完整解析整棵 JSON 树。

3.2 json_each:把 JSON 对象展开成行

json_each 是一个表函数,把 JSON 对象的顶层元素展开为键值对行,典型用法是配合LATERALSELECT * FROM tj_test, LATERAL JSON_EACH(j);。其运行结果见下(原文档中的示例截图):

从源码结构看,json_each在 BE 中实现为表函数(table function),位于 be/src/exprs/table_function/json_each.h,这也解释了为什么它必须出现在FROM子句而非普通的SELECT表达式位置。

3.3 get_json_* 系列:面向字符串的便捷取值

get_json_intget_json_doubleget_json_string直接接受 JSON 字符串和路径两个参数,省去先PARSE_JSON再取值的步骤。从源码结构看,json_functions.h 中这些函数签名是[json_string, tagged_value](两个BinaryColumn入参,返回对应标量列),与json_query接受JsonColumn入参形成两套入口,便于在不同数据类型场景下选用。

四、JSON 操作符:比较规则

StarRocks 支持以下 JSON 比较操作符:<<=>>==!=,可用它们查询 JSON 数据;但不允许使用IN查询 JSON 数据。规则如下(摘自 JSON operators 文档):

  • 操作符的两个操作数都必须是 JSON 值;若一个是 JSON、另一个不是,则非 JSON 操作数会在运算期间按 CAST 的转换规则转为 JSON 值。
  • 同类型操作数
    • 若两者都是 NUMBER、STRING、BOOLEAN 等基本类型,则按该基本类型的算术/比较规则执行;若一方是 DOUBLE、另一方是 INT,则 INT 先转换为 DOUBLE。
    • 若两者都是 OBJECT 或 ARRAY 等复合类型,则先按第一个操作数中键的顺序对双方键做字典序排列,再逐键比较值。
  • 不同类型操作数:按类型序比较,规则为NULL < BOOLEAN < ARRAY < OBJECT < DOUBLE < INT < STRING

文档给出了两个可复现的对比示例:

-- 示例 1:按第一个操作数的键序比较键 a 的值:1 < 2,故前者更小 SELECT PARSE_JSON('{"a": 1, "c": 2}') < PARSE_JSON('{"b": 1, "a": 2}'); -- 返回 1 -- 示例 2:键 a 的值相等(1 = 1),再比较键 c:第二个操作数没有键 c,故前者更大 SELECT PARSE_JSON('{"a": 1, "c": 2}') < PARSE_JSON('{"b": 1, "a": 1}'); -- 返回 0 -- 跨类型比较:STRING 位于 OBJECT 之后(NULL < BOOLEAN < ARRAY < OBJECT < DOUBLE < INT < STRING) SELECT PARSE_JSON('"a"') < PARSE_JSON('{"a": 1, "c": 2}'); -- 返回 0

需要留意的是示例 2 的结论方向:键a相等后,第一个操作数多出了键c,因此判定{"a": 1, "c": 2}大于{"b": 1, "a": 1}<的比较结果为 0。

五、JSON 路径表达式:StarRocks 支持的语法

JSON 路径表达式用于查询 JSON 对象中的元素,其数据类型为 STRING,在大多数情况下与JSON_QUERY等各类 JSON 函数配合使用。StarRocks 的路径语法并不完全遵循 SQL/JSON 路径规范,官方以如下 JSON 对象为例说明支持的符号:

{ "people": [{ "name": "Daniel", "surname": "Smith" }, { "name": "Lily", "surname": "Smith", "active": true }] }
JSON 路径符号说明路径示例返回值
$表示根 JSON 对象'$'整个根对象(people数组含两个元素)
.表示子 JSON 对象'$.people'people数组(两个对象)
[]表示一个或多个数组索引,[n]表示第 n 个元素,索引从 0 开始。StarRocks 2.5 支持查询多维数组,例如["Lucy", "Daniel"], ["James", "Smith"],用$.people[0][0]可查询 "Lucy" 元素'$.people[0]'{ "name": "Daniel", "surname": "Smith" }
[*]表示数组中的所有元素'$.people[*].name'["Daniel", "Lily"]
[start: end]表示数组元素的一个子集,由[start, end]区间指定,不包含 end 索引对应的元素'$.people[0: 1].name'["Daniel"]

注意切片区间是左闭右开语义:$.people[0:1].name只取到索引 0 为止。另外,如前文 parse_json 示例所示,键中包含.等符号时需要在路径中转义("a\\.1")或用引号整体包裹键名('"a.1"')。

5.1 源码视角:路径解析器如何对应这套语法

从源码结构看,be/src/exprs/jsonpath.h 中的JsonPath/JsonPathPiece结构正是上述语法的实现:JsonPathPiece::parse负责把路径字符串解析为「键 + 数组选择器」的序列,而数组选择器被抽象为ArraySelector及其四类子类——ArraySelectorSinglearr[x]取第 x 个元素)、ArraySelectorWildcardarr[*]取全部元素)、ArraySelectorSlicearr[1:3]取切片)以及ArraySelectorNone,与路径表达式表格中[n][*][start:end]三种写法一一对应。JsonPath还提供了starts_withrelativize(例如把$.a.b[1]相对$.a化为$.b[1])等方法,为 JSON 列的扁平化存储(flat JSON)提供路径前缀匹配能力;BE 存储层还有配套的 be/src/storage/json_path_deriver.h,可推断 StarRocks 会把高频查询路径推导为物化子列,这正是「用生成列/路径物化加速 JSON 查询」建议背后的实现基础。

六、实践要点小结

  1. 构造与解析:用json_object/json_array拼 JSON、用parse_json把字符串转 JSON;解析失败统一返回NULL,写条件判断时可用json_existsIS NOT NULL甄别脏数据。
  2. 取值:优先用箭头函数->json_query按路径取元素,路径越界或键不存在都返回NULL;面向字符串的轻量取值场景用get_json_int/get_json_double/get_json_string
  3. 变形与展开json_remove删除指定路径数据,json_set(见 json_set 文档)插入或更新,json_each把对象展开成行,json_keysjson_length做元信息提取。
  4. 比较:六种比较操作符可用,IN不可用于 JSON;复合类型按「首操作数键序 + 字典序」比较,跨类型按NULL < BOOLEAN < ARRAY < OBJECT < DOUBLE < INT < STRING排序。
  5. 路径语法:牢记$.[n](0 起)、[*][start:end](右开)五个符号;多维数组下标(2.5 起)与含特殊字符键的转义写法按第五节表格使用。
  6. 性能:对反复查询的 JSON 路径,文档建议采用生成列物化,配合 BE 端 flat JSON 路径推导机制降低每行解析开销。

相关参考文档均位于 docs/en/sql-reference/sql-functions/json-functions/ 目录;BE 端实现可进一步查阅 be/src/exprs/json_functions.cpp、be/src/exprs/jsonpath.cpp 与 be/src/types/simple_json_path.h。

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 5:45:10

登录注册全链路拆解:从表单校验到JWT安全加固

登录注册这功能&#xff0c;乍一看无非就是两个表单配两个接口&#xff0c;但真要在生产环境里把它做扎实&#xff0c;中间藏的细节能写满好几页。我做全栈开发这几年&#xff0c;见过太多项目在账号体系上翻车&#xff0c;有些是上线第一天就被脚本刷注册&#xff0c;有些是用…

作者头像 李华
网站建设 2026/9/18 5:44:53

AI小说创作系统:动态技能组合与进化引擎实践

1. 项目概述&#xff1a;当小说创作遇上AI进化力去年帮朋友调试小说生成脚本时&#xff0c;我发现一个有趣现象&#xff1a;大多数AI写作工具在生成3-5个章节后就会陷入重复套路。这促使我尝试用Agent技术构建一个真正具备进化能力的创作系统——它不仅能写故事&#xff0c;还能…

作者头像 李华
网站建设 2026/9/18 5:41:21

Security-101 应用安全核心概念(AppSec Key Concepts)深度指南

Security-101 应用安全核心概念&#xff08;AppSec Key Concepts&#xff09;深度指南 【免费下载链接】Security-101 8 Lessons, Kick-start Your Cybersecurity Learning. 项目地址: https://gitcode.com/GitHub_Trending/se/Security-101 应用安全&#xff08;AppSec…

作者头像 李华
网站建设 2026/9/18 5:39:53

React Native鸿蒙深度链接适配与优化实战

1. React Native鸿蒙深度链接适配实战&#xff1a;从原理到推送跳转优化作为一名在React Native跨平台开发领域深耕多年的开发者&#xff0c;我深刻理解在OpenHarmony平台上实现深度链接&#xff08;Deep Linking&#xff09;的痛点。不同于Android和iOS相对成熟的生态&#xf…

作者头像 李华
网站建设 2026/9/18 5:36:41

知漫剧实测:AI漫画动态化生成短剧全流程解析与效率对比

1. 认识知漫剧&#xff1a;把“漫画图”变成“剧”的AI生产线1.1 知漫剧到底是什么先解释清楚一件事&#xff1a;知漫剧不是传统意义上的视频剪辑软件&#xff0c;也不是单纯的角色扮演聊天工具。它本质上是把“静态漫画/图片变成动态短剧”的AI生产管线&#xff0c;核心链路是…

作者头像 李华
网站建设 2026/9/18 5:36:31

Hermes Agent实战:用oh-my-hermes打造统一AI Agent配置环境

如果你最近在技术社区刷到 Hermes Agent 这个词&#xff0c;可能第一反应是&#xff1a;又一个 AI Agent 框架&#xff1f;我也不例外。我最初看到它时&#xff0c;以为只是把聊天机器人包装了一层命令行&#xff0c;直到我把它接到 DeepSeek 的模型接口上&#xff0c;跑完一个…

作者头像 李华