我使用简单的SPARQL查询查询API:
PREFIX ...
SELECT DISTINCT *
WHERE {
?item dct:date ?date .
?item dct:title ?title .
?item rdfs:info ?info .
}
这会给我一个xml
<results>
<result>
<binding name='title'>
<literal>titletitle</literal>
</binding>
<binding name='info'>
<uri>link</uri>
</binding>
<binding name='date'>
<literal datatype='http://www.w3.org/2001/XMLSchema#dateTime'>2012-12-21T02:26:00+00:00</literal>
</binding>
<binding name='item'>
<uri>link</uri>
</binding>
</result>
...
</results>
但问题是:我知道,有一个以上的rdfs:info链接与此项目匹配。我如何查询以获得
...
<binding name='info'>
<uri>link1</uri>
</binding>
<binding name='info'>
<uri>link2</uri>
</binding>
<binding name='info'>
<uri>link3</uri>
</binding>
...
?这很简单,还是我需要一个子查询或一些奇怪的UNION
?
如果我试试
PREFIX ...
SELECT DISTINCT *
WHERE {
?item dct:date ?date .
?item dct:title ?title .
OPTIONAL (?item rdfs:info ?info1 ).
OPTIONAL (?item rdfs:info ?info2 ).
}
将返回?info1
和?info2
值的所有可能排列。另外,我不知道信息项的数量。
如果我添加FILTER (?info1 != ?info2)
,我仍会得到一些排列。我认为从代数的角度来看,FILTER (?info1 < ?info2)
可以放弃排列。但是如何在uris上应用<
?
答案 0 :(得分:2)
我害怕你不能这样做。 SELECT
(或者实际上是任何WHERE
)的结果是表格式的,您不能拥有嵌套表(在某些关系数据库中找到)或任何其他合适的结构。
直接选项是在现有查询中添加ORDER BY ?item
。这将至少将所有内容保持在一起,因此您可以逐项处理。在过去,我已经编写了包装器来迭代这样的关系数据,允许类似:
foreach (item: iterateOverBy(results, "item")
foreach (date: iterateOverBy(results, "date")
foreach (title: iterateOverBy(results, "title")
foreach (info: iterateOverBy(results, "info")
...do something...
但是SPARQL当然可以返回RDF,所以你可以使用:
CONSTRUCT { ?item dct:date ?date ; dct:title ?title ; rdfs:info ?info }
WHERE ...
在内部会做同样的工作,但结果不会像SELECT
那样包含很多重复。
我的最终建议不适合给出的问题,但我应该提及它。
到目前为止,实际的查询处理并没有真正改变,只是结果的形式。但是假设查询格式在哪里:
WHERE {
...some condition to select items...
?item dct:date ?date .
?item ... as before ...
}
条件可能是FILTER (?date > ...something...)
或?item rdf:type ex:InterestingItem
,或者其他。
在这种情况下,您可以考虑DESCRIBE
:
DESCRIBE ?item WHERE { ...some condition to select items... }
这将返回(在rdf中)有关与该条件匹配的项目的信息。这里的查询只是挑选出项目,而不是我们想要了解的内容。