我在为我的数据库进行SPARQL查询时遇到了一些麻烦。
课堂上有个人(材料)(材料组)。 每种材料都有一些特性,如密度,拉伸强度等, 但并非所有材料都包含所有材料。
我需要进行查询,我将为每个属性输入范围值,如果材料具有该属性, 将我的值范围与材料的值范围进行比较。
我用子查询做了这个,并且因为每个属性可以有更多的值由空白节点链接,但它不起作用。
我希望得到如下结果:
材料| propertyLabel | minValue |包括maxValue
mat01 |抗拉强度250 | 250
mat02 |抗拉强度255 | 280
mat01 |密度| 4800 | 4900
mat02 |密度| 5000 | 5010
我的查询如下:
SELECT DISTINCT ?material ?propertyLabel ?minValue ?maxValue WHERE {
?material rdf:type/rdfs:subClassOf* res:Material . #Get all materials
{ OPTIONAL {
SELECT ?material ?propertyLabel (MIN(?value) AS ?minValue) (MAX(?value) AS ?maxValue) WHERE {
?material pro:hasDensity [ unit:hasValue ?value ; unit:hasUnit ?unit ] .
pro:hasDensity rdfs:label ?propertyLabel .
} GROUP BY ?material ?propertyLabel
HAVING ((MAX(?value) > 4500) && (MIN(?value) < 10000))
} }
{ OPTIONAL {
SELECT ?material ?propertyLabel (MIN(?value) AS ?minValue) (MAX(?value) AS ?maxValue) WHERE {
?material pro:hasUltimateTensileStrength [ unit:hasValue ?value ; unit:hasUnit ?unit ] .
pro:hasUltimateTensileStrength rdfs:label ?propertyLabel .
} GROUP BY ?material ?propertyLabel
HAVING ((MAX(?value) > 50) && (MIN(?value) < 300))
} }
# Other properties...
}
附加信息
好的,这里有更清晰的代码和澄清......
是的,VALUES的答案现在有效,但是......
它输出的材料甚至对一个属性和该属性都有价值, 但我需要的是满足他们所拥有的所有属性的材料。
所以我们说我们有材料:
res:m1
res:m2
res:m3
和材料属性:
pro:hasYieldStrenght
pro:hasMeltingPoint
Pro:hasDensity
通过空白节点将属性链接到它们的值和单位(对于范围)。
材质1有一些属性1,该属性可以有多个值(1,2,3 ..这就是我使用MIN和MAX的原因),如下所示:
res:m1 pro:hasYieldStrength
[ unit:hasValue "100"^^xsd:double ; unit:hasUnit unit:MegaPascal ] ,
[ unit:hasValue "133"^^xsd:double ; unit:hasUnit unit:MegaPascal ] ;
某些材料没有某些属性(它们在现实世界中是未知的,或者它们不在数据库中)。
现在,我想如何搜索资料,我想说我想要所有资料: 亲:hasDensity 2000 - 3000 亲:hasMeltingPoint 250 - 400
所以我需要挖掘搜索值的范围交叉点以及db中特定属性的最小值和最大值。
这就是我的原因:
HAVING ((MAX(?value) > ?low) && (MIN(?value) < ?high))
如果我只在输入上设置一个属性,那么所有这些都有效。
但是当我想搜索多个交叉点(属性)时,结果包含每个材质的属性, 所以,让我们说材料只满足其中一个属性,那么属性和材料就会出现。
我需要的是满足所有属性 IF 的材料。
如果材料对某些财产没有价值(没有人测量它让我们说)并且满足所有其他财产,那么应该在该财产上有或没有空值的结果中考虑,但如果材料失败为了满足一个属性,那么它不应该被考虑在结果中,不仅仅是对于那个属性,而且通常是那个材料。
这就是为什么我在考虑OPTIONAL,但我已经失去了它,因为我花了两天的价值这个错误:p
这是新代码:
SELECT ?m ?p (MAX(?value) AS ?maxValue) (MIN(?value) AS ?minValue) WHERE {
VALUES (?p ?low ?high)
{
( pro:hasDensity 1 300 )
( pro:hasYieldStrength 30 300 )
( pro:hasMeltingPoint 100 350 )
}
?m ?p [ unit:hasValue ?value ; unit:hasUnit ?unit ]
} GROUP BY ?m ?p ?low ?high
HAVING ((MAX(?value) > ?low) && (MIN(?value) < ?high))
它甚至不考虑密度,因为它们都没有密度低, 这是结果:
m p maxValue minValue
#m74653522 #hasYieldStrength 110.0 100.0
#m36767231 #hasYieldStrength 262.0 220.0
#Phosphorus #hasMeltingPoint 317.0 317.0
另一方面,有些材料密度低,但不考虑其他性能不满意的材料。 (就像它第一排属性中的问题我不知道......)
答案 0 :(得分:1)
如果没有看到您的数据,很难确切地说出问题是什么,但听起来您的数据类似于以下内容,其中每种材质都有几个属性值。在这种情况下,两种材料 m1 和 m2 ,对于属性 p1 和 p2 (其中也有标签):
@prefix : <urn:ex:>
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
:p1 rdfs:label "P one" .
:p2 rdfs:label "P two" .
:m1 :p1 10, 12, 14, 16 ;
:p2 90, 100, 110, 120 .
:m2 :p1 11, 13, 15, 17 ;
:p2 95, 105, 115, 125 .
听起来你想为每个属性指定下限和上限,然后对于每个属性和一对边界,检索每个实例的边界内的所有属性值,并记录最大值和最小值。每种材料的财产。以下查询通过指定值块中的属性和边界来执行此操作。 (如果您不熟悉值块,请参阅附录。)结果如下。
prefix : <urn:ex:>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?material
?pLabel
(min(?value) as ?min)
(max(?value) as ?max)
where {
values (?p ?lowerBound ?upperBound) {
(:p1 12 15)
(:p2 97 116)
}
?material ?p ?value .
?p rdfs:label ?pLabel .
filter ( ?lowerBound <= ?value && ?value <= ?upperBound )
}
group by ?material ?pLabel
order by ?pLabel ?material
----------------------------------
| material | pLabel | min | max |
==================================
| :m1 | "P one" | 12 | 14 |
| :m2 | "P one" | 13 | 15 |
| :m1 | "P two" | 100 | 110 |
| :m2 | "P two" | 105 | 115 |
----------------------------------
在SPARQL 1.1中,使用值块可以替换,例如
{ ?s :p1 :o1 }
union
{ ?s :p2 :o2 }
带
values (?p ?o) {
(:p1 :o1)
(:p2 :o2)
}
?s ?p ?o
这是使用union而不是值的等效查询:
prefix : <urn:ex:>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?material
?pLabel
(min(?value) as ?min)
(max(?value) as ?max)
where {
{
?material :p1 ?value .
:p1 rdfs:label ?pLabel .
filter ( 12 <= ?value && ?value <= 15 )
}
union
{
?material :p2 ?value .
:p2 rdfs:label ?pLabel .
filter ( 97 <= ?value && ?value <= 116 )
}
}
group by ?material ?pLabel
order by ?pLabel ?material