名称: writing-hashql-jexpr 描述: ‘HashQL J-Expr 语法用于编写查询。在使用 J-Expr 代码时使用,使用 #literal/#struct/#list 构造,理解函数调用语法,或处理 HashQL 查询文件 (.jsonc)。’ 许可证: AGPL-3.0 元数据: 触发器: 类型: domain 强制执行: suggest 优先级: high 关键词: - J-Expr - jexpr - hashql 查询 - hashql 语法 - “#literal” - “#struct” - “#list” - “#tuple” 意图模式: - “\b(write|read|create|parse)\b.?\b(j-?expr|hashql)\b" - "\b(hashql|jexpr)\b.?\b(query|syntax|expression)\b”
编写 HashQL J-Expr
J-Expr 是 HashQL 的一种基于 JSON 的表达式语法。它使用 JSON 原语表示类型化表达式。
表达式类型
J-Expr 有三种表达式类型:
| JSON 类型 | J-Expr 含义 |
|---|---|
| 字符串 | 路径/标识符/符号 |
| 数组 | 函数调用 |
| 对象 | 数据构造器(使用 # 键) |
路径(字符串)
字符串被解析为路径或标识符:
"x" // 简单变量
"vertex.id.entity_id" // 点号路径访问
"::core::types::String" // 命名空间/根路径
"::graph::head::entities" // 图函数路径
函数调用(数组)
数组表示函数调用:[函数, 参数1, 参数2, ...]
// 基本函数调用
["add", {"#literal": 1}, {"#literal": 2}]
// 命名空间函数
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
// 带标签的参数,对象中使用 :prefix
["greet", {":name": {"#literal": "Alice"}}]
// 简写标签参数(带 :prefix 的字符串)
["func", ":name"]
数据构造器(带有 # 键的对象)
带有特殊 # 键的对象构造数据:
| 键 | 用途 | 示例 |
|---|---|---|
#literal |
原始值 | {"#literal": 42} |
#struct |
命名字段 | {"#struct": {"x": ...}} |
#list |
可变大小有序列表 | {"#list": [...]} |
#tuple |
固定大小有序元组 | {"#tuple": [...]} |
#dict |
键值映射 | {"#dict": {"k": ...}} |
#type |
类型注释 | 与其他键结合使用 |
字面量
{"#literal": 42}
{"#literal": "hello"}
{"#literal": true}
{"#literal": null}
{"#literal": 3.14, "#type": "Float"}
结构体
{"#struct": {"name": {"#literal": "Alice"}, "age": {"#literal": 30}}}
{"#struct": {"x": {"#literal": 1}}, "#type": "Point"}
列表和元组
{"#list": [{"#literal": 1}, {"#literal": 2}]}
{"#tuple": [{"#literal": 1}, {"#literal": "text"}]}
字典
{"#dict": {"key": {"#literal": "value"}}}
常见模式
Let 绑定
["let", "varName", {"#literal": 10}, ["add", "varName", {"#literal": 5}]]
函数定义
["fn", {"#tuple": []}, {"#struct": {"vertex": "_"}}, "_", body_expr]
条件语句
["if", condition_expr, then_expr, else_expr]
比较
["==", "left", "right"]
[">", {"#literal": 5}, {"#literal": 3}]
建议做法
- 对所有原始值(数字、字符串、布尔值、null)使用
#literal - 对命名空间路径使用
::前缀 - 对带标签的参数使用
:前缀 - 将
#type与其他构造器结合用于类型注释
避免做法
- 不要使用裸露的 JSON 数字/布尔值 - 用
{"#literal": ...}包装 - 不要混淆
#list(可变大小)和#tuple(固定大小) - 对带标签的参数不要使用
#前缀(应使用:) - 不要错误嵌套
#键 - 每个对象应有一个主#键
示例
实体查询:
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
带比较的筛选:
["filter", "entities",
["fn", {"#tuple": []}, {"#struct": {"entity": "_"}}, "_",
["==", "entity.draft_id", {"#literal": null}]]]
带类型的结构体:
{"#struct": {"value": {"#literal": 100}}, "#type": "Amount"}