[英]How to query the distance between two things with SPARQL
我使用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>
让我们以更易读的Turtle语法(如下)查看数据。 StopD使用ex:via属性连接到三个空白节点。 这意味着您将使用StopD ex:via* ?mid
获得?mid
四场比赛。 不过,您将一无所获,因为没有来自空白节点的出站链接,其属性为ex:via。 这意味着?mid ex:via+ StopC
没有匹配项,因为?mid没有任何传出的 ex:via链接。 ?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属性 。 例如, 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.