Download OpenAPI specification:
用只读 Cypher 查知识网络:标签是对象类,关系类型是关系类,属性是逻辑属性名。 本服务不自带查询语言实现——它把请求带着调用方身份转给 bkn-backend,由那边按 知识网络的模型把 Cypher 编译成一条 SQL 下发,再把行返回来。
与其他查询入口的分工:
query_object_instance:
单个对象类的平面过滤,不跨关系。query_instance_subgraph
/ explore_subgraph:要的是子图(节点 + 边的拓扑)。run_sql:绕开本体直查物理表。
本接口表达不了的口径(CTE、窗口函数)或资源没建成对象类时才落到那里。不需要 resource_id,也不需要物理列名——名字全部取自
schema-search.yaml 的 search_schema 或
kn-explore.yaml 的 get_object_types / get_relation_types。
授权:由 bkn-backend 按调用方账户裁决——语句点名的每个对象类与关系类都要有
query_data(网络级授权会继承到其下的对象类与关系类),再往下 vega 对每个资源
校验读取权限。无权查询的概念在编译用的模型里直接不存在,写了只会报「未知标签」,
而不是「无权」,所以不能拿本接口探测模型里有什么。本服务只做转发,不放大调用方能
读的范围。
认证:Authorization: Bearer <token>(OAuth access token 或 bak_ AppKey)。
编译并执行一条只读 Cypher 语句。支持的子集:
Unsupported)。{prop: value}。-[:R]->、<-[:R]-、无向 -[:R]-,每条必须指名一个关系类;
一条查询的模式最多 8 条关系、9 个节点(不与其他节点相连的节点也各算一张表)。
关系可以带变量(-[r:R]->),用于在 RETURN 里返回关系本身;关系没有自己的属性,r.x 会被拒绝。count(可选侧的属性) 得 0 而不是整行
消失(count(*) 仍然算 1 行)——按邻居数排序又不丢零度邻居,用的就是这一点。
它自带的 WHERE 与内联属性决定这条关系匹配到什么,不决定哪些行留下。
限制:首个子句必须是 MATCH;一条 OPTIONAL MATCH 只能写一条关系、只能引入一个
新节点(两端都已匹配或两端都是新节点都会被拒);它引入的节点不能被后面的 MATCH
或查询的 WHERE 再要求,否则留下来的行会被重新删掉,这类查询一律拒绝而不是照做。= <> < > <= >=(不等于写 <>,!= 也接受,按 <> 处理),
两边可以都是属性(o.shipped < o.ordered、a.code = b.code;模型声明为字符串和数字的属性不能互比),
日期写 date('2026-08-13') / datetime(...),只能和日期类属性比较;IN [...]、IS NULL / IS NOT NULL,
STARTS WITH / ENDS WITH / CONTAINS,用 AND / OR / NOT 组合,可加括号。
值可写 $name 参数;IN $list 可把整个列表作为一个参数传入。字符串谓词左侧须为
变量.属性,右侧须为字符串字面量或取值为字符串的参数;按 openCypher 语义做字面
子串匹配(%、_ 等不是通配符),属性为 null 时不匹配;大小写是否敏感取决于
数据源列的排序规则(collation)。只能用于字符串属性,用在数值、日期等属性上返回 400。AS 别名、DISTINCT,以及 count / sum / avg /
min / max(含 count(*) 与 DISTINCT 形式)。count(n) 统计节点 n 存在的行,
count(DISTINCT n) 按主键统计不同对象(多个主键属性按组合区分,没有主键的对象类不能用)。有聚合时按 RETURN 中其余
列自动分组——这是 Cypher 的隐式 GROUP BY,无需也不能自己写 GROUP BY(写了会报语法错误并提示)。
RETURN 也可以返回条件,写法与 WHERE 相同,如 g.tournament_name CONTAINS 'Men' AS mens:
值为 true / false,无法判定时(属性为 null,或 OPTIONAL MATCH 没匹配到节点)为
null;它和其他返回值一样参与分组。要按条件排序,请先起别名再按别名排序。t 与关系 r。节点返回对象类和完整主键(主键值按声明类型
以精确文本给出),再加上 object_properties 里点名的属性;关系返回关系类、两端节点的标识和
连接两端的键值对。collect(x) 把每组的 x 收成列表(保留重复、跳过 null),{k: x} 构造映射。
节点和关系按标识分组,所以 RETURN t AS team, count(*) AS n 按每个对象计数,一次调用就拿到
对象和计数。这类查询总是作为一条 SQL 执行;带 collect 时每个结果行是一个结论(collect 以外的
返回值),LIMIT 按结论计数,保留下来的结论带全部证据。证据达到 10000 行时返回 400
BknBackend.Cypher.ReadBudgetExceeded,不会返回部分证据。图值不能用于 ORDER BY 或 DISTINCT,
collect 不能和其他聚合混用,collect 旁只能返回节点、关系、属性或常量,并只能按返回属性的别名排序。+ - * / % 与取负,可加括号,可写在 RETURN(含聚合的参数)、
WHERE 比较的两侧和 ORDER BY 里,如 count(*) * 2、sum(o.price * o.qty)、
count(o.x) * 1.0 / count(*)、WHERE o.amount * o.rate > $floor、
ORDER BY count(g.id) * 0.5 + p.rank * 0.3 DESC。操作数是数值属性、聚合、数字或
取值为数字的参数;字符串、布尔、null 与非数值属性返回 400。与 openCypher 语义不一致的
写法一律拒绝而不是照做:两个整数相除(Cypher 丢余数,各 SQL 库不一致),要小数结果把
一边乘 1.0;% 只用于整数;除以字面量 0;^ 乘方。聚合只能出现在 RETURN 与
ORDER BY 里,不能写在 WHERE 中。一个列或排序键既有聚合又在聚合外直接读属性(如
o.x - avg(o.x))时,该属性须同时作为单独的列返回,结果按它分组;DISTINCT 结果要按
算出来的值排序,请在 RETURN 里给它起别名再按别名排序。没有声明类型的属性交给数据源决定。
IN 列表、内联属性、SKIP / LIMIT 里仍不能写算术。CASE WHEN … THEN … ELSE … END、CASE x WHEN v THEN … END 与
coalesce(a, b, …) 能写在算术能写的地方:RETURN、WITH、ORDER BY、比较两侧和聚合参数,如
sum(CASE WHEN g.penalty = '1' THEN 1 ELSE 0 END)、count(CASE WHEN … THEN 1 END)。没有 ELSE 且没命中时为 null。
各分支(或参数)须都是数字或都不是数字(null 字面量可搭配任一种),不能返回布尔;字符串结果不能参与算术或
sum / avg;分支条件里的聚合要先在 WITH 里命名再用;简单形式不能写 WHEN null。这类查询总走 SQL 路径。MATCH (p1:产品 {material_number: $a})-[:产品关联产品bom]->(b1:产品BOM)-[:产品bom关联物料]->(m:物料)<-[:产品bom关联物料]-(b2:产品BOM)<-[:产品关联产品bom]-(p2:产品 {material_number: $b}) RETURN DISTINCT m.material_code。collect([DISTINCT] x.p),第二个 WITH 把第一个列表传下去,RETURN 只写大小:
MATCH … WITH collect(DISTINCT a.p) AS l1 MATCH … WITH l1, collect(DISTINCT b.q) AS l2 RETURN size([x IN l1 WHERE x IN l2]) AS common, size(l1) AS n1, size(l2) AS n2,返回一行;
第二段没匹配到时没有行。不能直接返回列表,要列出共有的值用上面的共享节点写法;不支持 UNWIND。MATCH (g:goal)-[:rel_goal_team]->(t:team) WITH t, count(*) AS n WHERE n > 100 RETURN t.name AS team, n ORDER BY n DESC。
WITH 里的值须用 AS 命名,节点可直接传下去(WITH t,按对象的主键分组,同名对象不会合并)。
WITH 的 WHERE 用 WITH 传下来的名字、节点的属性、由它们算出的值、字面量或参数比较:只涉及分组键的条件在分组前过滤,
涉及聚合的条件对每个分组判断。可以连写多个 WITH:只有第一个能聚合,后面的用前面的名字算新值并各自过滤,
如 WITH code, stock - usage * 50 AS gap WHERE gap < 0。第一个 WITH 里的 collect(x.p) AS s 只能写成
size(s),即收集到的个数(如 WHERE size(s) = 3)。RETURN 取 WITH 的名字、传下来节点的属性或由它们算出的值;
不聚合的 WITH 之后可以再写 count(*);聚合的 WITH 之后,RETURN 也可以只写聚合(如 RETURN count(*) AS n、
max(n)),对分组再统计,返回一行。以下仍拒绝:第二个 WITH 之后再写 MATCH、第二段 MATCH 之后再接 WITH(比较两个列表除外)、WITH DISTINCT、WITH *、WITH 上的
ORDER BY / SKIP / LIMIT、WITH 的 WHERE 里写 IN / 字符串谓词、第一个之后的 WITH 再聚合。WITH ['382-000005', 'P61-000351'] AS products MATCH (p:产品) WHERE p.material_number IN products …,
后面 MATCH 的条件按名字使用这些值。MATCH … WITH DISTINCT x.p AS v MATCH … WHERE y.q = v RETURN …,或
WITH collect(x.p) AS s MATCH … WHERE y.q IN s;v 也可以写在内联属性里({q: v})。第二段的每一行
只要值在第一段的值里就保留一次,不随第一段的重复而重复(半连接)。第一段的属性和行范围与查询中其他部分一样
受授权约束。WITH 只能有一项;不写 DISTINCT 时,RETURN 须写 DISTINCT 且不聚合;v 只能在 WHERE 顶层以
= 使用、s 只能以 IN 使用,不能放在 OR / NOT 下;第二段之后不能再接 WITH。WITH p, count(g) AS total WHERE total >= 10 MATCH (p)<-[:R]-(g2)-[:S]->(t) RETURN p, t, count(g2) AS n, total。WITH 传下来的每一行按主键和下一段
匹配到的行连接,下一段里节点可不写标签;total 可在 RETURN / ORDER BY 中使用和计算,用在含聚合的表达式里
时要同时单独返回;不能写在下一段的 WHERE 里。每个传下来的节点都要在下一段用到,下一段不能是 OPTIONAL MATCH,
之后不能再接 WITH。任何 WITH 之后,RETURN 都可以直接返回传下来的节点。这类查询总走 SQL 路径。数据集和索引:对象类绑定数据集或索引(不是 SQL 数据源),或一条查询跨多个数据源时,改为通过资源数据接口 逐表读取再关联,只支持基础写法;CASE、coalesce、对分组再统计、比较两个列表、把节点传给下一个 MATCH、 collect 会返回 400,读取量过大或超时也返回 400;返回节点、关系和虚拟边与 SQL 数据源上相同;UNION 也可用,每段各自读取。
不支持(会被拒绝,报错指名是哪个语法与位置):
变长路径 [:R*1..3]、XOR、date() / datetime() / localdatetime()、coalesce()、size()(只用于 WITH 收集的列表)和聚合以外的函数调用、^ 乘方、写操作(CREATE / MERGE / DELETE /
SET / REMOVE)。
行数:不写 LIMIT 默认返回 1000 行;LIMIT 不得超过 10000。
关系唯一性:按 openCypher 语义,同一条路径里共用同一关系类的多跳互不相同,
编译器会自动补上主键不等的条件,调用方不必自己写。该规则按子句划分,因此
OPTIONAL MATCH 的那一跳不参与——它补出的条件会落在 WHERE 里,正好删掉外连接
保住的行。
| response_format | string Default: "json" Enum: "json" "toon" 响应格式。 |
object (BKNContext) BKN Trace business-provenance context identifying the business
conversation and interaction to which this call belongs. Required on
MCP business tools and REST execution APIs while capture is enabled
and Trace Core is available;
optional on REST reads and Naming it makes the call managed: the service records an Operation under that interaction and attempts to return a receipt and capture evidence. Omitting it entirely, or sending an empty object, makes an eligible REST read or proxy call ad hoc. Only those two shapes are ad hoc — one id without the other, or a misspelt field, is refused rather than quietly downgraded. Both required child fields are server-issued handles and must not be invented by the caller:
These handles are available only through the provenance MCP tool above.
The BKN Trace Core session APIs under | |
| kn_id required | string 知识网络 ID,来自 |
| branch | string 分支名。不传按主分支查。 |
| query required | string 只读 Cypher 语句,语法子集见端点说明。 |
object 语句里 | |
object 返回的节点除标识外还要带哪些属性,按节点变量给出,如 | |
| explain | boolean 为 true 时不执行查询、不读数据,只返回 |
| timeout_sec | integer >= 1 查询在数据源上的执行时限(秒),查询执行的所有语句(UNION 的各分支、bind-join 及其 SQL 回退)共用这一个时限。不传则使用 bkn-backend 配置的时限(默认 55 秒,部署可通过
|
{- "kn_id": "kn_retail",
- "query": "MATCH (c:customer)<-[:rel_order_customer]-(o:order)-[:rel_order_item_order]->(i:order_item) WHERE c.city = 'Shanghai' AND o.status IN ['paid', 'shipped'] RETURN c.name AS customer, o.order_no AS order_no, i.sku AS sku LIMIT 100"
}{- "plan": { },
- "limited": true,
- "columns": [
- {
- "name": "string",
- "type": "string"
}
], - "entries": [
- { }
], - "value_types": { },
- "execution": {
- "match_rows": 0,
- "match_complete": true,
- "conclusions_limited": true
}
}