本文介绍了使用SPARQL定位具有多次出现的相同属性的主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to use SPARQL to return triples where the same subject has multiple objects for the same property, like so:

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

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

I feel like such a query should make use of property paths:

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

我正在使用Jena 2.6.4运行此属性路径查询,但没有得到任何结果.这是由于耶拿吗?还是我对查询的措词不正确?以下查询返回我期望的结果,但效果不佳:

I'm running this property-path query using Jena 2.6.4, but I'm not getting any results. Is this due to Jena? Or am I phrasing the query incorrectly? The following query returns the results I expect, but is inelegant:

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的所有功能.

The property-path query returns results if I use, say, example:property{1,2} or example:property{1}; just not the results I want. So, I know Jena is interpreting the syntax correctly, but I also know this is an older version of Jena, and so it might not recognize all the features of SPARQL 1.1.

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

I feel like this is a common kind of query, and should have a more elegant solution (and really, a cookbook solution). Am I right in using property paths to solve this problem, or should I take a different approach? And if I should use property paths, am I using them correctly?

推荐答案

让我们使用此数据:

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

没有属性路径

像这样的查询会产生?subjects,它们对example:property具有两个不同的值:

Without property paths

A query like this produces ?subjects that have two distinct values for 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:

This is pretty much what you've already got, though. To get it down to one result, you can select distinct:

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

关于属性路径

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

About property paths

Property paths are a way of expressing chains of properties (forward and backward) without needing to bind all the individual resources along the way, which is especially important if a variable number of edges are to be allowed. You can bind the things at either end of the chain, but not the things in the middle.

以图形方式显示的数据如下:

The data, graphically, looks like this:

        example:object1← example:subject→ example :object2

        example:object1 ← example:subject → example:object2

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

If you wanted to select the two objects that are related to some subject, you could use a property path. The path from example:object1 to example:object2 is (^example:property)/example:property, because you follow an example:property edge backward to example:subject, and then follow an example:property edge forward to example:object2. If you wanted the objects, but not the subject, you could use the following query:

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

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

I don't think there's a convenient way to get the subject using a property path. You could do something like

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

?subject移至某个对象,然后返回某物(即,不一定是?subject,然后再次移出,然后返回?subject),但是您将无法保证存在两个不同的对象了.

to go from ?subject to some object, then back to something (i.e., not necessarily ?subject, then out again, and then back to ?subject, but you wouldn't be getting the guarantees that there are two distinct objects anymore.

9.1属性路径语法中介绍了SPARQL属性路径的路径语言. SPARQL 1.1查询语言建议(W3C标准)的a>.值得注意的是,它包含p{n}表示法,即第3部分"Path Language" 确实如此.这意味着您的模式

The path language for SPARQL property paths is described in section 9.1 Property Path Syntax of the SPARQL 1.1 Query Language recommendation (the W3C standard). Notably, it doesn't include the p{n} notation that Section 3 Path Language of the earlier working draft did. This means that your pattern

?subject example:property{2} ?object

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

isn't actually legal SPARQL (though some implementations might support it). However, according to the working drafts, we can still determine what it means. To match this pattern, you'd need data of the form

       ?subject→ []→ ?object

        ?subject → [] → ?object

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

where [] just indicates some arbitrary resource. This isn't the same shape as the data that you've actually got. So even if this syntax were legal in SPARQL 1.1, it wouldn't give you the type of result that you're looking for. In general, the property paths are essentially a type of regular expression for property chains in the data.

虽然财产链可以使某些事情变得非常好,而使其他一些不可能的事情成为可能(例如,请参见我对的答案,是否有可能获得SPARQL中RDF集合中元素的位置?),我认为它们不适合这种情况.我认为您最好的选择,也是一个比较优雅的解决方案,是:

While property chains can make some things very nice, and some otherwise impossible things possible (e.g., see my answer to Is it possible to get the position of an element in an RDF Collection in SPARQL?), I don't think that they're appropriate for this case. I think that your best bet, and a rather elegant solution, is:

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

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

because it most plainly captures the intended query, "find ?subjects with two distinct values of example:property."

这篇关于使用SPARQL定位具有多次出现的相同属性的主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 05:13