【问题标题】:Using SPARQL to locate a subject with multiple occurrences of same property使用 SPARQL 定位具有多个相同属性的主题
【发布时间】:2013-09-20 14:51:02
【问题描述】:

我正在尝试使用 SPARQL 返回三元组,其中同一主题有多个对象用于同一属性,如下所示:

example:subject1 example:property example:object1
example:subject1 example:property example:object2

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

SELECT ?subject WHERE {
  ?subject example:property{2} ?object .
}

我正在使用 Jena 2.6.4 运行此属性路径查询,但没有得到任何结果。这是因为耶拿吗?还是我对查询的措辞不正确?以下查询返回我期望的结果,但不优雅:

SELECT ?subject WHERE {
  ?subject example:property ?object1 .
  ?subject example:property ?object2 .
  FILTER(!(?object1=?object2))
}

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

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

【问题讨论】:

  • 感谢您的接受,很高兴回答对您有所帮助。顺便说一句,answers.semanticweb.com 上有一个 related question,关于 sparql.org 上的 SPARQL 验证器拒绝使用 dc:title{2} 的查询。

标签: rdf sparql jena


【解决方案1】:

让我们使用这个数据:

@prefix example: <http://example.org/> .
example:subject1 example:property example:object1 .
example:subject1 example:property example:object2 .

没有属性路径

这样的查询会产生?subjects,其中example:property 有两个不同的值:

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

不过,这几乎是您已经拥有的。要将其归结为一个结果,您可以select distinct

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

关于属性路径

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

数据在图形上如下所示:

        示例:object1 &leftarrow;example:property 示例:主题 &rightarrow;example:property 示例:object2

如果您想选择与某个主题相关的两个对象,您可以使用属性路径。从example:object1example:object2 的路径是(^example:property)/example:property,因为您沿着example:property 边缘向后example:subject,然后沿着example:property 边缘向前 em> 到example:object2。如果您想要对象而不是主题,可以使用以下查询:

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

认为有一种方便的方法可以使用属性路径获取主题。你可以做类似的事情

?subject property/^property/property/^property ?subject

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

SPARQL 属性路径的路径语言在 SPARQL 1.1 查询语言推荐(W3C 标准)的9.1 Property Path Syntax 部分进行了描述。值得注意的是,它包括早期工作草案的Section 3 Path Language 所做的p{n} 表示法。这意味着你的模式

?subject example:property{2} ?object

实际上不是合法的 SPARQL(尽管某些实现可能支持它)。但是,根据工作草案,我们仍然可以确定它的含义。要匹配此模式,您需要格式为

的数据

        ?subject &rightarrow;example:property [] &rightarrow;example:property ?object

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

结论

虽然属性链可以使某些事情非常变得很好,而使某些原本不可能的事情成为可能(例如,参见 my answerIs it possible to get the position of an element in an RDF Collection in SPARQL?),但我认为它们不适合这个案例。我认为您最好的选择和相当优雅的解决方案是:

?subject example:property ?object1, ?object2 .
filter( ?object1 != ?object2 ).

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

【讨论】:

    猜你喜欢
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 2019-06-24
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多