想象你走进一家老式图书馆。这里没有整齐的表格,只有成千上万张卡片,每张卡片只记录一条事实:“姚明出生在上海”“上海位于中国”。卡片固定为三格:谁、什么关系、指向谁。你要找“出生在中国的人”,不能靠翻单一目录,只能顺着卡片上的线索一级一级跳。SPARQL 就是管理员教你的标准检索单:告诉他要返回哪一列、按什么图模式匹配、用什么条件筛选、顺着几条边跳。它之于知识图谱,正如 SQL 之于关系数据库。读完本文你会明白,SPARQL 不是关键词堆砌,而是一种“用图模式描述你要什么”的思维方式。

岗位关联

掌握 SPARQL,等于拿到知识图谱的“标准查询接口”。无论你做知识图谱问答、语义检索还是企业数据中台,它都是一把用得上的钥匙。

目录
  1. 可视化演示
  2. 基础语法结构:图书检索单的三件套
  3. RDF 三元组:目录卡片的三个固定格子
  4. 图模式匹配:把卡片拼成一张拼图
  5. FILTER 过滤:安检门而不是改造机
  6. 多跳路径查询:顺着关系链条找人
  7. 聚合与排序:按出版社统计藏书量
  8. 应用与推理:让图中的隐形关系现形
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示SPARQL查询语言的核心机制,通过入门/进阶/实战/优化四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

SPARQL查询语言:SPAR SPARQL语言定位与基础语法 三元组模式与基本图匹配 核心机制可视化 SPARQL查询语言整体架构与关键组件

基础语法结构:图书检索单的三件套

走进图书馆,管理员递给你一张空白检索单。单子上三栏:一栏写“我要哪个字段”(书名、作者、编号),一栏写“按什么条件找”(作者是莫言),旁边有一个小约定框,预先约定好简写“文学类=文:”。SPARQL 的骨架正是这张检索单:SELECT 表示“我要哪些变量”,WHERE 大括号里写“匹配什么样的图模式”,PREFIX 则提前声明命名空间的短名。

查询执行时,引擎把 WHERE 里的模式当模板,去整张知识图谱里找匹配。它像管理员把卡片柜里的所有卡片翻一遍,凡是能让模式成立的组合都放进答案。PREFIX 更像简称表:把长长的 URI 缩成 rdf:、foaf: 这样的词,让检索单写得短而清晰。这种“先声明别名、再写模式”的结构,是 SPARQL 区别于自由文本查询的核心设计。

合上检索单,你已经会写 SPARQL 的最小骨架:PREFIX 约定简写,SELECT 挑出要的列,WHERE 描述卡片的形状。剩下的语法,都是在丰富这张检索单的填写方式。

Q=SELECT  ?s  WHERE  { ?s  rdf:type  foaf:Person }Q = \mathrm{SELECT} \; ?s \; \mathrm{WHERE} \; \{\, ?s \; \mathrm{rdf:type} \; \mathrm{foaf:Person} \,\}
这条查询问的是:找出所有类型为 Person 的资源。它把“要什么”与“怎么找”分开,正是检索单的数字化表达。
  1. Q 的语义整条查询可以看作一个从知识图谱到答案集的函数,输出所有满足条件的 ?s。
    Q(G)={ s∣(s,  rdf:type,  foaf:Person)∈G }Q(G) = \{\, s \mid (s,\; \mathrm{rdf:type},\; \mathrm{foaf:Person}) \in G \,\}
  2. SELECT ?s?s 是绑定变量,相当于检索单上勾选的返回列,只有它会被输出。
    π?s(G)\pi_{?s}\bigl(G\bigr)
  3. WHERE 花括号花括号内的三元组模式是匹配条件,所有模式必须同时成立。
    ⋀i=1k  ti(x⃗)⊆G\bigwedge_{i=1}^{k} \; t_i(\vec{x}) \subseteq G
  4. PREFIX 与命名空间rdf: 与 foaf: 是命名空间简写,展开后是完整的 URI 前缀。
    foaf:=0\mathrm{foaf:} = \text{0}

RDF 三元组:目录卡片的三个固定格子

图书馆里每张卡片都固定分成三格,不允许写第四格。第一格是主体名称,第二格是关系标签,第三格是目标内容。RDF 三元组完全复刻了这种设计:(主语, 谓语, 宾语) 是知识图谱的最小事实单元。若干个三元组放在一起,就构成一个有向图。

主语和宾语都可以用 URI 标识——URI 就像图书的全球唯一编号,保证“姚明”不会和同名的人混淆。宾语还可以是字面量,比如数字 1980、字符串“上海”,对应卡片角落里写的普通文字。谓语则是一条有向边的标签,决定两个资源之间是什么关系。

现在你明白卡片的三格结构了。SPARQL 的一切模式匹配,本质上都是在这三格上做文章——用变量替换其中任意一格。

G={ (s1,p1,o1), (s2,p2,o2), …, (sn,pn,on) }G = \{\, (s_1,p_1,o_1),\ (s_2,p_2,o_2),\ \dots,\ (s_n,p_n,o_n) \,\}
知识图谱 G 就是三元组的集合。每一行都对应卡片上的三格内容,顺序不能换。
  1. G 的含义G 是整个 RDF 图谱的有穷集合,是查询执行的数据基础。
    G={(si,pi,oi)}i=1nG = \{ (s_i, p_i, o_i) \}_{i=1}^{n}
  2. 每个三元组(s, p, o) 表示一条有向边,p 从 s 指向 o。
    s→ p os \xrightarrow{\,p\,} o
  3. 主语与宾语s 是资源主体,o 是目标资源或字面量,二者角色不能互换。
    s,o∈URI∪Literals, o \in \mathrm{URI} \cup \mathrm{Literal}
  4. 谓语约束p 必须是 URI,因为它最终要表达“哪种关系”。
    p∈URIp \in \mathrm{URI}

图模式匹配:把卡片拼成一张拼图

单张卡片只能回答“姚明出生在哪”这种单跳问题。但真实问题是“出生在中国的人有谁”,需要把两张卡拼起来:先找 ?person 出生地 ?place,再找 ?place 位于 中国。共同的变量 ?place 就是两张卡片的咬合处。图模式匹配做的正是这件事:用变量把多个三元组模板联成一幅拼图,去整张图中找能同时填满所有空洞的赋值方案。

SPARQL 用空格或点号分隔多个三元组模式,它们之间是“逻辑与”关系。如果某个属性不一定存在,可以用 OPTIONAL 表示可缺失;如果希望“满足 A 或 B 其中一个即可”,可以用 UNION 做并集。这些语法都围绕同一个核心:把图结构拆成可组合的模板。

图模式匹配是 SPARQL 的灵魂。你不需要告诉引擎“怎么走”,只需要描述“最终长什么样”,引擎会自动完成拼图。

A={ v⃗  ∣  { t1(v⃗), t2(v⃗), …, tk(v⃗) }⊆G }A = \Big\{\, \vec{v} \;\Big|\; \{\, t_1(\vec{v}),\ t_2(\vec{v}),\ \dots,\ t_k(\vec{v}) \,\} \subseteq G \,\Big\}
查询答案 A 是变量向量 v 的集合,其中每个三元组模式 t_i(v) 都能在图中找到对应边。
  1. 答案集合 A查询结果是一个列表,每一行是一组变量绑定。
    A={v⃗1,v⃗2,…}A = \{ \vec{v}_1, \vec{v}_2, \ldots \}
  2. 模式实例化t_i(\vec{v}) 表示把三元组模板里的变量替换成具体值。
    ti:(变量)↦(具体资源)t_i: (\mathrm{变量}) \mapsto (\mathrm{具体资源})
  3. 子集条件所有实例化后的三元组必须都属于图谱 G,缺一不可。
    { t1,t2,…,tk }⊆G\{\, t_1, t_2, \ldots, t_k \,\} \subseteq G
  4. 逻辑与连接模式之间是合取关系,等价于 SQL 多表 JOIN 的图版本。
    t1∧t2∧⋯∧tkt_1 \wedge t_2 \wedge \cdots \wedge t_k

FILTER 过滤:安检门而不是改造机

管理员从卡片柜翻出一摞候选卡片,但你要的只有 2000 年之后出版的书。这时你会让管理员站在门口,手里拿着筛子:年份不过关的卡片一律留下。SPARQL 的 FILTER 就是这把筛子,它逐行检查候选绑定,只放行满足条件的行。

FILTER 支持比较运算(大于、小于、等于)、逻辑组合(AND、OR、NOT)、字符串正则匹配(REGEX 函数)以及类型检查(ISURI、ISLITERAL)。要注意的是,FILTER 只会筛选,不会创造新三元组,也不会修改图谱。它是在图模式匹配完成后、结果输出前执行的一道安检。

FILTER 是安检门:它只检查已经找到的候选,不负责制造新知识。这条边界,正是初学者最容易踩的坑。

R′=σ  ?year≥2000  ∧  ?pages>300(R)R' = \sigma_{\;?year \geq 2000 \;\wedge\; ?pages > 300}\bigl(R\bigr)
原始候选集合 R 经过条件筛选后变为 R',只有同时满足两个条件的行被保留。
  1. R 代表候选集图模式匹配产生的全部中间结果行。
    R={bindings from pattern matching}R = \{ \text{bindings from pattern matching} \}
  2. σ 选择算子来自关系代数,表示“按条件过滤行”。
    σθ(R)\sigma_{\theta}(R)
  3. 复合条件?year ≥ 2000 与 ?pages > 300 都必须为真。
    θ=(?year≥2000)∧(?pages>300)\theta = (?year \geq 2000) \wedge (?pages > 300)
  4. R' 结果集过滤后的结果可以继续参与下游排序或聚合。
    R′=R∖{ r∣θ(r)=false }R' = R \setminus \{\, r \mid \theta(r) = \mathrm{false} \,\}

多跳路径查询:顺着关系链条找人

你想认识“王教授”,但目录卡片上没有任何人与王教授直接相连,只写着“李老师认识王教授”。管理员要做的,是从你的名片出发,沿着“认识”这条关系链走一步,再走一步,直到找到王教授。这种沿多条边连续遍历的查询,就是多跳路径查询。

SPARQL 处理多跳有两种方式:一种是把多个三元组模式显式写出来,像上一节的拼图;另一种是用属性路径语法,把整条链压缩成一个表达式。?x ex:同事+ ?y 表示经过至少一条同事边;* 表示零条或任意多条;? 表示零条或一条;{n,m} 表示限定步数范围。属性路径让多跳查询像写正则表达式一样简洁。

多跳查询让“查关联”成为可能。推荐系统、社交网络分析、反欺诈链路,本质都是在这个语法之上构建复杂的路径遍历。

?person  →  出生地    ?place  →  位于    中国?person \;\xrightarrow{\;\mathrm{出生地}\;}\; ?place \;\xrightarrow{\;\mathrm{位于}\;}\; \mathrm{中国}
两跳展开形式:先沿出生地边到地点,再沿位于边到中国,两条边首尾相接。
  1. 起点?person遍历从任意资源开始,逐个候选人员尝试。
    start=?person\mathrm{start} = ?person
  2. 第一跳经过 出生地 谓词,到达中间节点 ?place。
    ?person→出生地?place?person \xrightarrow{\text{出生地}} ?place
  3. 第二跳经过 位于 谓词,到达常量 中国。
    ?place→位于中国?place \xrightarrow{\text{位于}} \text{中国}
  4. 属性路径简写用斜杠连接谓词,等价于上述显式两跳。
    ?person  ex:出生地/ex:位于  中国?person \;\mathrm{ex:出生地/ex:位于}\; \mathrm{中国}

聚合与排序:按出版社统计藏书量

管理员想回答“哪个出版社的书最多”,他不会把每本书都列给你看,而是先按出版社分组,再统计每组数量,最后按数量从大到小排列。SPARQL 的聚合与排序正是这套操作:GROUP BY 负责分组,COUNT、SUM、AVG、MIN、MAX 负责统计,ORDER BY 负责排序,LIMIT 则截取前 N 条。

聚合查询常与 DISTINCT 配合,去掉重复的实体。比如“每个出版社出版了多少位知名作家”就比“每位作家在哪出版”更难写,因为作者可能有多本书。分组统计之后,你得到的是浓缩过的知识图谱画像,而不是原始三元组。

聚合查询让知识图谱从“事实库”升级为“统计报表”。无论运营看板还是数据中台,这一步都是取数分析的关键。

n(p)=∣ { b  ∣  (b,  出版社,  p)∈G } ∣n(p) = \left|\, \{\, b \;\mid\; (b,\; \mathrm{出版社},\; p) \in G \,\} \,\right|
n(p) 统计以 p 为出版社的图书数量,是 COUNT 聚合的数学表达。
  1. n(p) 聚合函数输入一个出版社 p,输出该社图书数量。
    n:URI↦Nn: \mathrm{URI} \mapsto \mathbb{N}
  2. 集合筛选花括号内筛选所有谓语为“出版社”、宾语为 p 的图书 b。
    Bp={ b∣(b, 出版社, p)∈G }B_p = \{\, b \mid (b,\ \mathrm{出版社},\ p) \in G \,\}
  3. 基数计数竖线表示集合大小,即统计符合条件的元素个数。
    n(p)=∣Bp∣n(p) = |B_p|
  4. 分组排序SPARQL 中写作 GROUP BY ?p,再配合 ORDER BY DESC(n)。
    GROUP BY  ?p  ⇒  ORDER BY  n  DESC\mathrm{GROUP\,BY} \; ?p \;\Rightarrow\; \mathrm{ORDER\,BY} \; n \; \mathrm{DESC}

应用与推理:让图中的隐形关系现形

图书馆里藏着很多“未被写下的知识”:卡片只说北京在中国、中国在亚洲,但读者问“北京在哪个洲”时,管理员能推理出北京在亚洲。这种通过传递关系推出新结论的能力,就是语义推理。SPARQL 在推理引擎配合下,可以查询到图谱中没有显式写出的三元组。

知识图谱问答系统(KBQA)则是推理与大模型的结合:用户用自然语言提问,系统把问题解析成意图和实体,再翻译成 SPARQL 查询,最后在图上执行并把结果组织成自然语言答案。语义检索也受益于此——它能理解“出生在上海的运动员”是跨两条边的关系,而不是几个关键词的简单叠加。

应用与推理把 SPARQL 从“查询语言”推向“认知引擎”。大模型负责理解语言,知识图谱负责精确推理,二者交汇处正是下一代 AI 应用的舞台。

(A,  位于,  B)  ∧  (B,  位于,  C)  ⟹  (A,  位于,  C)(A,\; \mathrm{位于},\; B) \;\wedge\; (B,\; \mathrm{位于},\; C) \;\Longrightarrow\; (A,\; \mathrm{位于},\; C)
当“位于”是传递关系时,从 A 到 B、再从 B 到 C 两条边可以推出 A 到 C 的隐含边。
  1. 前件一事实 A 位于 B,在图谱中显式存在。
    (A, 位于, B)∈G(A,\ \mathrm{位于},\ B) \in G
  2. 前件二事实 B 位于 C,同样显式存在。
    (B, 位于, C)∈G(B,\ \mathrm{位于},\ C) \in G
  3. 推理规则若关系被声明为传递属性,结论凭规则推出。
    (A,B)∧(B,C)(A,C)  transitivity\frac{(A,B) \wedge (B,C)}{(A,C)} \; \mathrm{transitivity}
  4. SPARQL 落地用属性路径 ex:位于+ 也能实现传递闭包查询,无需重写图谱。
    ?x  ex:位于+  ?y?x \;\mathrm{ex:位于+}\; ?y

AI 应用场景

知识图谱问答系统(KBQA)

阶段:语义理解与答案检索

解决的问题:用户问“上海出生的 NBA 球员有哪些”,关键词搜索只能匹配字面词,无法理解“上海出生”和“NBA 球员”是两个必须同时满足的关联条件。传统做法是分词加倒排索引,答案零散且不可解释。AI 先把问题解析成主题、谓词和目标实体,再自动生成 SPARQL 查询,在图谱上精确执行,返回结构化实体列表。

具体案例:在搜索引擎中输入“姚明出生地”,知识图谱卡片直接显示人物关系,而不是一堆网页链接。背后就是一次 SPARQL 多跳查询驱动。

电商语义检索引擎

阶段:索引构建与召回排序

解决的问题:用户输入“100 元以内的国产零食”,商品库若只存在关系表里,需要跨表 JOIN 多次,且无法表达“价格 < 100”与“产地 = 中国”的联合约束。将商品元数据转成 RDF 图谱后,一条 SPARQL 即可完成属性过滤、多跳关联和排序。

具体案例:电商平台的智能助手把“便宜的好评零食”这串口语转换成带 FILTER 与 ORDER BY 的 SPARQL 查询,线上响应时间从秒级降到毫秒级。

企业知识中台与推理

阶段:数据融合与隐式推理

解决的问题:不同业务系统的数据分散在多个数据库,字段含义不一致。统一建模为 RDF 后,SPARQL 能跨数据源做多跳查询;配合推理引擎,还能补全隐式关系,比如从“部门隶属”推导“员工归属”。

具体案例:医疗知识图谱中查询“与阿司匹林存在相互作用且用于高血压的药物”,通过属性路径和推理一步到位。

Python 演示

python32 行
from rdflib import Graph, URIRef, Literalfrom rdflib.namespace import RDF g = Graph()ex = "http://example.org/" yao = URIRef(ex + "姚明")liu = URIRef(ex + "刘翔")shanghai = URIRef(ex + "上海")china = URIRef(ex + "中国") g.add((yao, RDF.type, URIRef(ex + "运动员")))g.add((yao, URIRef(ex + "出生地"), shanghai))g.add((yao, URIRef(ex + "出生年份"), Literal(1980)))g.add((liu, RDF.type, URIRef(ex + "运动员")))g.add((liu, URIRef(ex + "出生地"), shanghai))g.add((liu, URIRef(ex + "出生年份"), Literal(1983)))g.add((shanghai, URIRef(ex + "位于"), china)) sparql = """PREFIX ex: <http://example.org/>SELECT ?person WHERE {  ?person ex:出生地 ?place .  ?place ex:位于 ex:中国 .  ?person ex:出生年份 ?year .  FILTER(?year >= 1980)}""" for row in g.query(sparql):    name = str(row.person).replace(ex, "")    print(name, "出生于中国")
目的:构造一个包含两名运动员、两个城市的最小 RDF 图谱,然后用 SPARQL 多跳查询+FILTER 找出出生在中国的运动员。
  1. from rdflib import Graph, URIRef, Literal导入建图与建节点所需的三个核心类。
  2. g.add((yao, URIRef(ex + "出生地"), shanghai))向图谱添加一条三元组,相当于填充一张目录卡片。
  3. sparql = """PREFIX ..."""用三引号定义完整 SPARQL 查询文本,保留换行与缩进。
  4. FILTER(?year >= 1980)在候选结果上做值过滤,只保留出生年份不小于 1980 的人。
  5. g.query(sparql)执行查询,返回可迭代的绑定行,每行访问 row.person 取得主语。

常见误区

误区既然都有 SELECT 和 WHERE,我把 SQL 知识照搬到 SPARQL 就能写对。表 JOIN 和图画模式不是一回事吗?

正解SQL 是在固定列名的二维表上做行列运算,JOIN 通过外键把行连起来;SPARQL 是在有向图上做子图同态匹配,变量可以出现在主语或宾语任意位置。就像图书管理员查卡片时是“按图索骥”地跨卡片找共同对象,而不是机械地拼表格行。两种语言的思维模型完全不同。

为何常见:两者语法外壳相似,SELECT/WHERE 关键词几乎同名,初学者容易把它当成 SQL 方言。

误区既然 FILTER 写在 WHERE 里面,那它应该能像三元组模式一样,帮我把两个实体“连起来”或者新建一条边。

正解FILTER 只能对候选绑定做布尔判断,类似安检门只检查行李,不负责制造行李。真正构造新关系的只能是三元组模式或推理规则。若在 FILTER 里写 ?a ex:朋友 ?b,引擎会直接报语法错误,因为 FILTER 体内只允许值表达式。

为何常见:FILTER 与三元组模式混写在同一个大括号里,位置上的接近让初学者误以为它们权限相同。

误区`?x ex:同事+ ?y` 看起来像正则表达式里的无限匹配,图上如果有环,查询会不会永远跑不完?

正解SPARQL 属性路径虽然借鉴了正则语法,但引擎实现基于图遍历(BFS/DFS),会维护已访问集合,天然防环。+ 表示“至少一条边”,* 表示“零条或任意条”,语义明确且可判定。真正要担心的是复杂路径产生指数级中间结果,而不是死循环。

为何常见:+ 和 * 的符号来自正则表达式,正则匹配确实可能回溯很久,人们把这种恐惧迁移到图查询上。

误区SPARQL 只能返回图谱里显式存在的三元组,所以“北京在亚洲”这种没写过的边永远查不出来。

正解只要图谱启用推理引擎,或查询中使用传递属性路径(如 ex:位于+),就能从已有事实推导出隐含结论。推理让知识图谱不只是存储容器,更是一个“可推导的认知底座”。前提是本体中声明了传递性,否则推理引擎不能凭空假设。

为何常见:RDF 三元组给人的第一印象是“显式事实的集合”,推理机制隐藏在标准底层,不主动了解就不会想到。

面试题

Q1. SPARQL 语言本质上解决什么问题?

单选题 · easy

  • A.RDF 三元组图数据的查询语言← 正确答案
  • B.关系数据库的标准查询语言
  • C.NoSQL 文档数据库专属查询语言
  • D.纯文本搜索引擎专用查询语法

答案:A。SPARQL 是 W3C 为 RDF 知识图谱制定的标准查询语言,面向图结构而非二维表。B 是 SQL 的功能,C 是文档数据库的功能,D 是全文检索的功能。

Q2. RDF 三元组由哪三部分组成?

单选题 · easy

  • A.主键、外键、索引
  • B.主语、谓语、宾语← 正确答案
  • C.表名、字段、值
  • D.节点、边、权重

答案:B。RDF 事实单元是 (主语,谓语,宾语),就像目录卡片的三格:谁、什么关系、指向谁。A 是关系数据库概念,C 是表格概念,D 是图论术语但不是 RDF 的标准称呼。

Q3. SPARQL 中用来声明命名空间简写的是哪个关键字?

单选题 · easy

  • A.SELECT:指定返回变量
  • B.PREFIX:声明命名空间别名← 正确答案
  • C.WHERE:定义图匹配范围
  • D.LIMIT:限制结果条数

答案:B。PREFIX 把长 URI 缩成短词,例如 PREFIX foaf: <http://...> 之后就能用 foaf:Person。SELECT 管输出,WHERE 管条件,LIMIT 管条数,都与命名空间无关。

Q4. 图谱中有 <姚明> <出生地> <上海> 和 <上海> <位于> <中国>,要找出“出生在中国的人”,正确的 SPARQL 是?

单选题 · mid

  • A.SELECT ?p WHERE { ?p ex:出生于 中国 }
  • B.SELECT ?p WHERE { ?p ex:出生地?x . ?x ex:位于 中国 }← 正确答案
  • C.SELECT ?p WHERE { ?p ex:位于 中国 }
  • D.SELECT ?p WHERE { ?p ex:家乡是 中国 }

答案:B。B 用变量?x 连接“出生地”和“位于”两条边,形成两跳路径:人→上海→中国。A、D 使用了图中不存在的谓词,C 只匹配“位于中国”的资源,无法表达“出生”这个条件。

Q5. FILTER(?age > 30) 在 SPARQL 查询中的作用是?

单选题 · mid

  • A.只保留年龄大于 30 的候选结果← 正确答案
  • B.把图中年龄小于 30 的数据删除
  • C.将年龄超过 30 的关系修改为非法
  • D.给年龄大于 30 的人添加新属性

答案:A。FILTER 是安检门,逐行检查候选绑定,放行条件为真的行。它不会修改、删除或插入任何三元组,所以 B、C、D 都是对 FILTER 权限的误解。

Q6. 关于 SPARQL 的 FILTER 子句,以下说法正确的有?

多选题 · mid

  • A.FILTER 可出现在 WHERE 块中← 正确答案
  • B.FILTER 支持跨三元组值比较← 正确答案
  • C.FILTER 能向图谱插入新三元组
  • D.FILTER 可使用 REGEX 正则匹配← 正确答案

答案:ABD。FILTER 写在 WHERE 块内,可以对多个变量做联合比较,也支持 REGEX(str, pattern) 正则匹配。它永远只筛值、不写图,因此 C 错误。

Q7. 属性路径 ?x ex:同事+ ?y 与 ?x ex:同事* ?y 的核心差异是?

单选题 · mid

  • A.加号至少一条边,星号零条或任意条← 正确答案
  • B.加号表示正向边,星号表示反向边
  • C.两者在查询结果上没有任何区别
  • D.加号用于属性路径,星号用于 FILTER

答案:A。+ 要求路径至少经过一条同事边,* 允许零条边(此时?x 与?y 可以相同)。二者都用于属性路径,但语义范围不同,B、C、D 均不符合 SPARQL 规范。

Q8. 下列哪些属于 SPARQL 的聚合函数?

多选题 · hard

  • A.COUNT 统计匹配行数← 正确答案
  • B.AVG 计算平均值← 正确答案
  • C.MIN/MAX 获取极值← 正确答案
  • D.REGEX 做正则过滤

答案:ABC。COUNT、AVG、MIN、MAX 都是 SPARQL 聚合函数,配合 GROUP BY 对分组结果做统计。REGEX 是过滤函数而非聚合函数,它用于 FILTER 中进行字符串模式匹配。

Q9. 关于 SPARQL 的 OPTIONAL 子句,下列说法正确的是?

单选题 · hard

  • A.匹配失败时该行补 NULL 仍返回← 正确答案
  • B.匹配失败时整行结果被直接丢弃
  • C.等价于 SQL 内连接且丢弃未匹配
  • D.只能用于可选数字类型的属性

答案:A。OPTIONAL 类似 SQL 的 LEFT JOIN:左边主模式匹配成功就保留该行,右边可选模式匹配不上就用未绑定值填充。B、C 是内连接行为,D 对谓词类型没有任何限制。

Q10. 给定图中存在路径 A →(p)→ B →(q)→ C →(r)→ D,哪些属性路径表达式能从 A 匹配到 D?

多选题 · extreme

  • A.ex:p/ex:q/ex:r← 正确答案
  • B.ex:p/ex:q*
  • C.ex:p/(ex:q/ex:r)*← 正确答案
  • D.ex:p/(ex:q|ex:r)?

答案:AC。A 连续走三条边到达 D;C 中 (q/r)* 重复一次恰好是 q 后接 r,也能到达 D。B 中 q* 最多到 C,缺少 r 边;D 中 (q|r)? 只能再走一步,最远到 C,均无法抵达 D。