知识图谱-你不知道的sparql的路径查询
2019-10-05 本文已影响0人
Huoyo
sparql语言是W3C制定并推荐的知识图谱查询语言
(⊙o⊙)…重要的话说到这里结束,废话少说,开始正文!
关于sparql,虽然网上的中文资料较少,但是也有些基本内容的叙述,此处不赘述,本文主要讲的是sparql的多重路径查询,以下通过一个很小的RDF例子来说明,RDF内容大概长这个样子,关于唐高祖李渊的家谱
<rdf:RDF
xmlns:ns1="http://www.huoyo.org/relationship/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<rdf:Description rdf:about="http://www.huoyo.org/person/李虎">
<ns1:儿子rdf:resource="http://www.huoyo.org/person/李昞"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.huoyo.org/person/李昞">
<ns1:儿子rdf:resource="http://www.huoyo.org/person/李渊"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.huoyo.org/person/李渊">
<ns1:儿子 rdf:resource="http://www.huoyo.org/person/卫怀王李玄霸"/>
<ns1:女儿 rdf:resource="http://www.huoyo.org/person/万春公主"/>
...等等省略一片
<ns1:儿子 rdf:resource="http://www.huoyo.org/person/鲁王李灵夔"/>
<ns1:儿子 rdf:resource="http://www.huoyo.org/person/荆王李元景"/>
<ns1:儿子 rdf:resource="http://www.huoyo.org/person/汉王李元昌"/>
<ns1:儿子 rdf:resource="http://www.huoyo.org/person/霍王李元轨"/>
<ns1:父亲 rdf:resource="http://www.huoyo.org/person/李昞"/>
</rdf:Description>
- 查询所有的三元组
select ?s ?p ?o ?results where
{
?s ?p ?o
}
- 查询李虎的儿子
# PREFIX 为资源前缀定义,为了在select中简写资源而定义
# 如:http://www.huoyo.org/person/李虎 ->p:李虎
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?o where
{
p:李虎 r:儿子 ?o
}
- 查询李虎的孙子
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re where
{
p:李虎 r:儿子 ?o . # . 一定不能省略
?o r:儿子 ?re #递推
}
- 查询李虎的曾孙
基本版
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re2 where
{
p:李虎 r:儿子 ?o . # . 一定不能省略
?o r:儿子 ?re . #递推
?re r:儿子 ?re2 #再递推
}
优化版
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re2 where
{
p:李虎 r:儿子/r:儿子/r:儿子 ?re2 # 有了/,老子是不是可以递推了
}
感觉关系有点长,真的要这样下去吗?有用过neo4j的cypher语句的可能知道,路径是可以跳着查询的,而不需要明确中间到底经过了哪些'儿子',sparql中有这种东东吗?有!
- 路径查询-李虎的儿子
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re2 where
{
p:李虎 (r:儿子){1} ?re2 # 有本事继续递推呀
}
- 路径查询-李虎的孙子
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re2 where
{
p:李虎 (r:儿子){2} ?re2 # 真的递推不动了
}
- 路径查询-李虎的儿子和孙子
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re2 where
{
p:李虎 (r:儿子){1,2} ?re2 # 突然感觉在哪里见过...
}
感觉怎么那么像正则表达式啊,正则里面还支持
这些,我得验证一下
- 路径查询-李虎子孙后代
# 根据图谱:
# 李虎-儿子->李昞
# 李昞-儿子->李渊
# 李渊->儿子-李世民
PREFIX p: <http://www.huoyo.org/person/>
PREFIX r: <http://rwww.huoyo.org/relationship/>
select ?re2 where
{
p:李虎 (r:儿子|r:女儿)+ ?re2
}
竟然成功了,妈妈再也不用当心我只会一层一层的递推了!
- 特别注意
在超级大的图中不要随意使用
,查询容易奔溃