使用SPARQL查找具有多个相同属性的主题

Ste*_*ley 4 rdf sparql jena

我试图使用SPARQL返回三元组,其中同一主题具有相同属性的多个对象,如下所示:

example:subject1 example:property example:object1
example:subject1 example:property example:object2
Run Code Online (Sandbox Code Playgroud)

我觉得这样的查询应该使用属性路径:

SELECT ?subject WHERE {
  ?subject example:property{2} ?object .
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Jena 2.6.4运行此属性路径查询,但我没有得到任何结果.这是由于耶拿吗?或者我错误地判断查询?以下查询返回我期望的结果,但是不优雅:

SELECT ?subject WHERE {
  ?subject example:property ?object1 .
  ?subject example:property ?object2 .
  FILTER(!(?object1=?object2))
}
Run Code Online (Sandbox Code Playgroud)

如果我使用,比如example:property{1,2}example:property{1},则属性路径查询返回结果; 只是不是我想要的结果.所以,我知道Jena正确地解释了语法,但我也知道这是Jena的旧版本,所以它可能无法识别SPARQL 1.1的所有功能.

我觉得这是一种常见的查询,应该有更优雅的解决方案(实际上,这是一本食谱解决方案).我是否正确使用属性路径来解决这个问题,或者我应该采取不同的方法?如果我应该使用属性路径,我是否正确使用它们?

Jos*_*lor 19

让我们使用这些数据:

@prefix example: <http://example.org/> .
example:subject1 example:property example:object1 .
example:subject1 example:property example:object2 .
Run Code Online (Sandbox Code Playgroud)

没有财产路径

像这样的查询会产生?subjects两个不同的值example:property:

prefix example: <http://example.org/>
select ?subject where { 
  ?subject example:property ?object1, ?object2 .
  filter ( ?object1 != ?object2 )
}
Run Code Online (Sandbox Code Playgroud)
--------------------
| subject          |
====================
| example:subject1 |
| example:subject1 |
--------------------
Run Code Online (Sandbox Code Playgroud)

不过,这几乎就是你已经拥有的.为了得到一个结果,你可以select distinct:

prefix example: <http://example.org/>
select distinct ?subject where { 
  ?subject example:property ?object1, ?object2 .
  filter ( ?object1 != ?object2 )
}
Run Code Online (Sandbox Code Playgroud)
--------------------
| subject          |
====================
| example:subject1 |
--------------------
Run Code Online (Sandbox Code Playgroud)

关于物业路径

属性路径是表达属性链(向前和向后)的一种方式,而不需要沿途绑定所有单独的资源,如果允许可变数量的边,这尤其重要.你可以绑定链的任何一端的东西,但不能绑定中间的东西.

图形上的数据如下所示:

        示例:object1← example:property example:subject→ example:property example:object2

如果要选择与某个主题相关的两个对象,可以使用属性路径.从路径example:object1example:object2(^example:property)/example:property,因为你关注的example:property边缘后退example:subject,然后按照一个example:property边缘向前example:object2.如果您想要对象而不是主题,则可以使用以下查询:

prefix example: <http://example.org/>
select * where { 
  ?object1 (^example:property)/example:property ?object2 .
  filter ( ?object1 != ?object2 )
}
Run Code Online (Sandbox Code Playgroud)

认为有一种方便的方法来使用属性路径获取主题.你可以做点什么

?subject property/^property/property/^property ?subject
Run Code Online (Sandbox Code Playgroud)

?subject某个对象转到某个对象(即,不一定?subject,然后再次出来,然后回到?subject,但是你不会得到保证有两个不同的对象了.

SPARQL属性路径的路径语言在SPARQL 1.1查询语言建议(W3C标准)的9.1属性路径语法一节中描述.值得注意的是,它没有包括早期工作草案的第3节路径语言所做p{n}注释.这意味着你的模式

?subject example:property{2} ?object
Run Code Online (Sandbox Code Playgroud)

实际上并不合法SPARQL(虽然有些实现可能支持它).但是,根据工作草案,我们仍然可以确定它的含义.要匹配此模式,您需要表单的数据

        ?subject→ example:property []→ example:property?object

其中[]只表示一些任意资源.这与您实际获得的数据形状不同.因此,即使这种语法在SPARQL 1.1中是合法的,它也不会为您提供您正在寻找的结果类型.通常,属性路径本质上是数据中属性链的一种正则表达式.

结论

虽然属性链可以做一些事情非常不错,和一些可能的,否则不可能的事情(例如,见我的回答是否有可能得到一个元素的位置在RDF集合SPARQL? ),我不认为他们"适合这种情况.我认为你最好的选择,一个相当优雅的解决方案是:

?subject example:property ?object1, ?object2 .
filter( ?object1 != ?object2 ).
Run Code Online (Sandbox Code Playgroud)

因为它最清楚地捕获了预期的查询,"找到?subject具有两个不同值的" example:property.