知识图谱:Freebase,服务器:virtuoso
SPARQL基本语法表

一个SPARQL样例
- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?x
- WHERE {
- FILTER (?x != ns:m.0160w)
- FILTER (!isLiteral(?x) OR lang(?x) = '' OR langMatches(lang(?x), 'en'))
- ns:m.0160w ns:location.country.currency_used ?x .
- }
大致意思是
在virtuoso服务器执行后,设置格式为html,结果如下。

此外,值得注意的是,对于
SELECT DISTINCT ?x
而言,若写为
SELECT DISTINCT ?x1 ?x2 ?x3
则返回满足后续(where子句里的)约束条件的(x1, x2, x3)组合。
最简单的形式
- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT ?e1 ?r ?e2
- where {?e1 ?r ?e2}
这表示,不加任何限制地,查询图谱内所有的三元组。返回结果自然就有很多:

可以看到返回结果的顶上,还写上了查询语句里我们自己命名的e1,r,e2。
加上一个三元组的约束
- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?e1 ?r
- WHERE {
- ?e1 ?r ns:m.0160w .
- }
即要求变量e1和r,满足三元组(?e1 ?r ns:m.0160w)。结果如下:

当然,我们还可以再嵌套其他的三元组(嵌套查询),比如
- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?e1 ?r
- WHERE {
- ?e1 ?r ns:m.0160w .
- ?e1 ns:freebase.user_profile.hometown ?e2 .
- }
显然,这里我们就加了两个三元组约束。结果的条数自然就少得多了。

- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?e1 ?r
- WHERE {
- ?e1 ?r ns:m.0160w .
- FILTER(?r=ns:freebase.user_profile.hometown)
- }
即过滤出(即,只要这部分)变量r是ns:freebase.user_profile.hometown的情况。结果如下:

- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?e1 ?r ?e2
- WHERE {
- ?e1 ?r ns:m.0160w .
- OPTIONAL { ?e1 ns:freebase.user_profile.hometown ?e2 }
- }
这样的话,第二个三元组约束就是可选满足的了,即若条件(?e1,ns:freebase.user_profile.hometown,?)成立,再查询?处的?e2;若不成立,就变量e2空着。部分结果显示如下:

可见结果和2.2已知单个三元组的条件查询,的结果几乎是一致的——只是最后多了e2一列。
- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?e1 ?r ?e2
- WHERE {
- { ?e1 ?r ns:m.0160w } UNION { ?e1 ns:freebase.user_profile.hometown ?e2 }
- }
可见,满足三元组条件1(?e1 ?r ns:m.0160w)或条件2(?e1 ns:freebase.user_profile.hometown ?e2)中任意一个,就返回。部分结果如下:

条件1 UNION 条件2,和, 条件1 OPTIONAL 条件2 的区别就在于:
- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT COUNT DISTINCT ?e1 ?r ?e2
- WHERE {
- { ?e1 ?r ns:m.0160w } UNION { ?e1 ns:freebase.user_profile.hometown ?e2 }
- }
此处与DISTINCT配合使用,即统计满足条件的无重复的e1,r,e2组合数量,结果如下:

- PREFIX ns: <http://rdf.freebase.com/ns/>
- SELECT DISTINCT ?e1 ?r
- WHERE {
- ?e1 ?r ns:m.0160w .
- ?e1 ns:freebase.user_profile.hometown ?e2 .
- FILTER(lang(?e1)!='zh')
- }
结合FILTER实现,即过滤出(只要这部分)语言不是中文(zh)的变量e1和r。

可见结果跟2.3嵌套查询是一致的。
参考博客: