我用RDF / XML创建了一个小地铁地图,并想知道如何查询两站之间的距离。我是SPARQL的新手,不知道如何开始。
“距离”是指,我想知道,两个站之间有多少站。后来,我想计算持续时间,但这是另一点。
这是我的第一个方法:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://example.com>
SELECT (count(?mid) as ?distance) WHERE {
<http://example.com/StopD> ex:via* ?mid .
?mid ex:via+ <http://example.com/StopC> .
}
我认为,我的查询不起作用,因为我使用空白节点?不起作用意味着,我没有得到两个停靠点之间的图形数量(如StopA和StopB)。我脑子里有这样的事情:http://answers.semanticweb.com/questions/3491/how-can-i-calculate-the-length-of-a-path-between-2-graph-nodes-in-sparql/24609
这是我的地图草图。这些行旁边的数字表示两个站点之间的行程持续时间:
我的RDF代码描述了每个电台及其邻居停靠的可用线路和行程持续时间。初看起来它看起来很冗余,但我想在将来包括单向路线(例如公交车),所以我认为第一次尝试是可以的。
RDF(在此处下载文件:http://gopeter.de/misc/metro.rdf)
<?xml version="1.0"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ex="http://example.com/">
<rdf:Description rdf:about="http://example.com/StopA">
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopB" />
<ex:Line rdf:resource="http://example.com/Line1" />
<ex:Duration>2</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopB" />
<ex:Line rdf:resource="http://example.com/Line2" />
<ex:Duration>7</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopD" />
<ex:Line rdf:resource="http://example.com/Line4" />
<ex:Duration>2</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopD" />
<ex:Line rdf:resource="http://example.com/Line2" />
<ex:Duration>6</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopE" />
<ex:Line rdf:resource="http://example.com/Line1" />
<ex:Duration>1</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopF" />
<ex:Line rdf:resource="http://example.com/Line4" />
<ex:Duration>3</ex:Duration>
</ex:via>
</rdf:Description>
<rdf:Description rdf:about="http://example.com/StopB">
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopA" />
<ex:Line rdf:resource="http://example.com/Line1" />
<ex:Duration>2</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopA" />
<ex:Line rdf:resource="http://example.com/Line2" />
<ex:Duration>7</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopC" />
<ex:Line rdf:resource="http://example.com/Line2" />
<ex:Duration>10</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopF" />
<ex:Line rdf:resource="http://example.com/Line3" />
<ex:Duration>2</ex:Duration>
</ex:via>
</rdf:Description>
<rdf:Description rdf:about="http://example.com/StopC">
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopB" />
<ex:Line rdf:resource="http://example.com/Line2" />
<ex:Duration>10</ex:Duration>
</ex:via>
</rdf:Description>
<rdf:Description rdf:about="http://example.com/StopD">
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopA" />
<ex:Line rdf:resource="http://example.com/Line2" />
<ex:Duration>6</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopA" />
<ex:Line rdf:resource="http://example.com/Line4" />
<ex:Duration>2</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopF" />
<ex:Line rdf:resource="http://example.com/Line3" />
<ex:Duration>2</ex:Duration>
</ex:via>
</rdf:Description>
<rdf:Description rdf:about="http://example.com/StopE">
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopA" />
<ex:Line rdf:resource="http://example.com/Line1" />
<ex:Duration>1</ex:Duration>
</ex:via>
</rdf:Description>
<rdf:Description rdf:about="http://example.com/StopF">
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopA" />
<ex:Line rdf:resource="http://example.com/Line4" />
<ex:Duration>3</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopB" />
<ex:Line rdf:resource="http://example.com/Line3" />
<ex:Duration>2</ex:Duration>
</ex:via>
<ex:via rdf:parseType="Resource">
<ex:Stop rdf:resource="http://example.com/StopD" />
<ex:Line rdf:resource="http://example.com/Line3" />
<ex:Duration>2</ex:Duration>
</ex:via>
</rdf:Description>
</rdf:RDF>
答案 0 :(得分:4)
让我们以更容易阅读的Turtle语法(下面)查看您的数据。 StopD使用ex:via属性连接到三个空白节点。这意味着您将?mid
与StopD ex:via* ?mid
进行四场比赛。但是,您不会再获得更多信息,因为空白节点没有外部链接,其属性为ex:via。这意味着?mid ex:via+ StopC
有没有匹配,因为?mid没有任何传出 ex:via links。像?mid ex:Stop/ex:via+ StopC
之类的东西会更好,因为ex:Stop链接会让你从空白节点到另一个停止点。
@prefix ex: <http://example.com/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
ex:StopD ex:via [ ex:Duration "6" ;
ex:Line ex:Line2 ;
ex:Stop ex:StopA
] ;
ex:via [ ex:Duration "2" ;
ex:Line ex:Line4 ;
ex:Stop ex:StopA
] ;
ex:via [ ex:Duration "2" ;
ex:Line ex:Line3 ;
ex:Stop ex:StopF
] .
即使您可以添加ex:Stop到您的属性路径,但这仍然不会按照您想要的方式计算距离,因为您不会仅限于一行。也就是说,你会在多条路径上获得优势。
我重新创建了一个更简单的场景:
@prefix : <https://stackoverflow.com/q/24538144/1281433/> .
# B
# * *
# 2 * * 4
# * *
# * *
# A +++++++++ C
# 3
#
# *** line 1
# +++ line 2
:StopA a :Stop ; :toLink :Link1 , :Link3 .
:StopB a :Stop ; :toLink :Link2 .
:StopC a :Stop .
:Link1 :hasDuration 2 ;
:toStop :StopB ;
:Line1Self :Link1 .
:Link2 :hasDuration 4 ;
:toStop :StopC ;
:Line1Self :Link2 .
:Link3 :hasDuration 3 ;
:toStop :StopC ;
:Line2Self :Link3 .
每个站点都可以连接到任意数量的链接:toStop。每条链接的行用rolification property表示。例如,link2 line1self link2
表示link2在line1上。这意味着我们使用属性路径“保持在正确的位置”。然后,要查找从第1行的stopA到stopB的行程持续时间,您可以使用如下查询:
prefix : <https://stackoverflow.com/q/24538144/1281433/>
select (sum(?duration) as ?length) where {
:StopA :toLink/(:toStop/:toLink)*/:Line1Self ?link .
?link :hasDuration ?duration ;
:toStop/(:toLink/:Line1Self/:toStop)* :StopC .
}
----------
| length |
==========
| 6 |
----------
要检查其他行,只需更改:LineXSelf属性即可。例如,对于第2行:
prefix : <https://stackoverflow.com/q/24538144/1281433/>
select (sum(?duration) as ?length) where {
:StopA :toLink/(:toStop/:toLink)*/:Line2Self ?link .
?link :hasDuration ?duration ;
:toStop/(:toLink/:Line2Self/:toStop)* :StopC .
}
----------
| length |
==========
| 3 |
----------
但这种方法有一些局限性。属性路径是您执行此类任意深度查询的唯一选项,但您不能在属性路径中使用变量,这意味着您无法执行以下操作来获取每条线路上的距离:
prefix : <https://stackoverflow.com/q/24538144/1281433/>
select ?line (sum(?duration) as ?length) where {
values ?line { :Line1Self :Line2Self }
:StopA :toLink/(:toStop/:toLink)*/?line ?link .
?link :hasDuration ?duration ;
:toStop/(:toLink/?line/:toStop)* :StopC .
}
group by ?line