在 SPARQL 中计算满足约束的值并为不满足约束的值返回 0 [英] Count values that satisfy a constraint and return 0 for those that don't satisfy it in SPARQL
问题描述
我想使用 SPARQL 查询检测满足属性值条件的所有值.
I want to detect all values that satisfy a condition on the value of a property using a SPARQL query.
例如,假设我想检测 rdfs:label
的值的类型为 xsd:string
的所有资源.
For example, imagine that I want to detect all resources in which the value of rdfs:label
has type xsd:string
.
逻辑中的定义可以是:
∀x(stringLabel(x) ≡ ∀y(rdfs:label(x,y)→xsd:string(y)))
∀x(stringLabel(x) ≡ ∀y(rdfs:label(x,y)→xsd:string(y)))
我在 SPARQL 中找到了一种方法:
I have found a way to do it in SPARQL as:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <http://example.org/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?s where {
# Count arcs with property rdfs:label
{ SELECT ?s (COUNT(*) AS ?c0) {
?s rdfs:label ?o .
} GROUP BY ?s
}
# Count arcs with property rdfs:label and value xsd:string
{ SELECT ?s (COUNT(*) AS ?c1) {
?s rdfs:label ?o . FILTER ((isLiteral(?o) && datatype(?o) = xsd:string))
} GROUP BY ?s
}
# filter out those resources that have rdfs:label
# with values not in xsd:string
FILTER (?c0 = ?c1)
}
对于以下数据似乎可以正常工作:
which seems to work ok with the following data:
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <http://example.org/> .
:peter rdfs:label "Peter" ; foaf:knows :anna .
:anna rdfs:label "Anna" .
:r22 rdfs:label 22 .
:x foaf:knows :r22 .
然而,它不返回值 :x
因为它没有 rdfs:label
并且它不返回 0 作为计数 c0代码>.
However, it does not return the value :x
because it does not have rdfs:label
and it does not return 0 as the count c0
.
有没有办法计算具有某些属性的资源对于没有该属性的资源返回 0?
Is there a way to count the resources that have some property returning 0 for the resources that don't have that property?
推荐答案
假设你有这样的数据,有些资源有 rdfs:label 值,有些没有,有些资源有,有些有 string值,有些具有非字符串值.
Suppose you've got data like this, where some resources have rdfs:label values, and some don't, and of those that do, some have string values, and some have non-string values.
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <http://stackoverflow.com/q/25316358/1281433/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
# a non-string label
:a rdfs:label 22 .
# one or more string labels
:b rdfs:label "hello"^^xsd:string .
:c rdfs:label "hello"^^xsd:string , "goodbye"^^xsd:string .
# no labels at all
:d rdfs:seeAlso :b .
然后您可以编写一个查询,首先匹配所有非文字资源,并过滤掉那些不符合指定条件的资源.也就是说,您只需过滤掉那些标签不是 xsd:string 的标签.
You can write a query then that begins by matching all the non-literal resources, and filtering out those that do not meet the specified criteria. That is, you simply filter out those that have a label that's not an xsd:string.
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <http://stackoverflow.com/q/25316358/1281433/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?s where {
#-- initially select all non-literals
?s :? ?s
filter ( !isLiteral(?s) )
#-- but filter out anything that has a
#-- a non-string label
filter not exists {
?s rdfs:label ?label
filter ( datatype(?label) != xsd:string )
}
}
------
| s |
======
| :c |
| :d |
| :b |
------
您当然也可以计算结果的数量:
You can of course count the number of results as well:
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <http://stackoverflow.com/q/25316358/1281433/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select (count(distinct ?s) as ?ns) where {
?s :? ?s
filter ( !isLiteral(?s) )
filter not exists {
?s rdfs:label ?label
filter ( datatype(?label) != xsd:string )
}
}
------
| ns |
======
| 3 |
------
或者,如果您想选择每个 ?s 以及它具有的 rdfs:labels 的数量,您也可以通过选择性地选择 ?s 确实具有的标签,按 ?s 分组,以及计算不同的 ?label 值:
Alternatively, if you want to select each ?s along with the number of rdfs:labels that it has, you can do that, too, by optionally selecting the labels that an ?s does have, grouping by ?s, and counting the distinct ?label values:
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <http://stackoverflow.com/q/25316358/1281433/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?s (count(distinct ?label) as ?nlabel) where {
?s :? ?s
filter ( !isLiteral(?s) )
filter not exists {
?s rdfs:label ?label
filter ( datatype(?label) != xsd:string )
}
#-- get the label for counting
optional {
?s rdfs:label ?label
}
}
group by ?s
---------------
| s | nlabel |
===============
| :d | 0 |
| :b | 1 |
| :c | 2 |
---------------
这篇关于在 SPARQL 中计算满足约束的值并为不满足约束的值返回 0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!