ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

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

StarRocks JSON 函数与操作符全景:构造函数、查询处理函数、JSON 操作符与路径表达式 StarRocks JSON 函数与操作符全景构造函数、查询处理函数、JSON 操作符与路径表达式【免费下载链接】starrocksThe worlds 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_object、json_array、parse_json、JSON 查询/处理函数箭头函数-、cast、get_json_*、json_query、json_remove、json_each、json_exists、json_keys、json_length、json_string、JSON 比较操作符、、,、、!以及 StarRocks 方言下的 JSON 路径表达式语法$、.、[n]、[*]、[start:end]。读完本文你可以直接掌握如何在 StarRocks 中构造、查询、修改和比较 JSON 数据并能结合 BE 源码如 json_functions.h 与 jsonpath.h理解这些函数在查询引擎中的实现方式进而在日志分析、用户画像等半结构化数据场景写出可运行的 JSON 查询。一、总览三类 JSON 能力StarRocks 文档将 JSON 能力划分为三组JSON 构造函数JSON constructor functions用于从零构造 JSON 对象、JSON 数组或把字符串解析为 JSON 值JSON 查询函数与处理函数JSON query functions and processing functions用于查询 JSON 内部元素按路径定位、在 JSON 与 SQL 类型之间转换、删除/展开/校验 JSON 数据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 文档keyJSON 对象的键仅支持 VARCHAR 类型valueJSON 对象的值支持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; -- 返回 12.3 源码视角这些函数在 BE 中如何落地从源码结构看上述构造函数都在 BE 端以向量化函数实现。be/src/exprs/json_functions.h 中的JsonFunctions类声明了parse_json、json_object、json_object_empty、json_array、json_array_empty等DEFINE_VECTORIZED_FN函数——参数与返回类型分别对应BinaryColumn字符串与JsonColumnJSON 列说明 StarRocks 对 JSON 采用了列式Column存储与向量化求值而非逐行标量计算。值得注意的是BE 源码中还存在json_set、json_pretty、json_contains、to_json、is_json_scalar等总览表之外、但仓库文档目录下已收录的函数可见实际函数面比总览页更宽。三、JSON 查询函数与处理函数用于查询和处理 JSON 数据。例如可以用路径表达式在 JSON 对象中定位某个元素。总览页收录的函数如下函数说明示例返回值箭头函数查询 JSON 对象中可通过路径表达式定位的元素SELECT parse_json({a: {b: 1}}) - $.a.b;1cast在 JSON 数据类型与 SQL 数据类型之间转换SELECT CAST(1 AS JSON);1get_json_double解析 JSON 字符串并从指定路径取出浮点值SELECT get_json_double({k1:1.3, k2:2}, $.k1);1.3get_json_int解析 JSON 字符串并从指定路径取出整数值SELECT get_json_int({k1:1, k2:2}, $.k1);1get_json_string解析 JSON 字符串并从指定路径取出字符串SELECT get_json_string({k1:v1, k2:v2}, $.k1);v1json_query查询 JSON 对象中可通过路径表达式定位的元素的值SELECT JSON_QUERY({a: 1}, $.a);1json_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);1json_keys以 JSON 数组形式返回 JSON 对象的顶层键若指定路径则返回该路径下的顶层键SELECT JSON_KEYS({a: 1, b: 2, c: 3});[a, b, c]json_length返回 JSON 文档的长度SELECT json_length({Name: Alice});1json_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; -- 返回 bjson_query的行为完全对应且数组索引越界时同样返回NULLSELECT 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_int、get_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_int、get_json_double、get_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 对象$.peoplepeople数组两个对象[]表示一个或多个数组索引[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_with与relativize例如把$.a.b[1]相对$.a化为$.b[1]等方法为 JSON 列的扁平化存储flat JSON提供路径前缀匹配能力BE 存储层还有配套的 be/src/storage/json_path_deriver.h可推断 StarRocks 会把高频查询路径推导为物化子列这正是「用生成列/路径物化加速 JSON 查询」建议背后的实现基础。六、实践要点小结构造与解析用json_object/json_array拼 JSON、用parse_json把字符串转 JSON解析失败统一返回NULL写条件判断时可用json_exists或IS NOT NULL甄别脏数据。取值优先用箭头函数-或json_query按路径取元素路径越界或键不存在都返回NULL面向字符串的轻量取值场景用get_json_int/get_json_double/get_json_string。变形与展开json_remove删除指定路径数据json_set见 json_set 文档插入或更新json_each把对象展开成行json_keys、json_length做元信息提取。比较六种比较操作符可用IN不可用于 JSON复合类型按「首操作数键序 字典序」比较跨类型按NULL BOOLEAN ARRAY OBJECT DOUBLE INT STRING排序。路径语法牢记$、.、[n]0 起、[*]、[start:end]右开五个符号多维数组下标2.5 起与含特殊字符键的转义写法按第五节表格使用。性能对反复查询的 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 worlds 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),仅供参考
返回列表