SPARQL查询。可选子查询和HAVING MIN MAX值

时间:2014-11-04 16:54:06

标签: rdf sparql

我在为我的数据库进行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

另一方面,有些材料密度低,但不考虑其他性能不满意的材料。 (就像它第一排属性中的问题我不知道......)

1 个答案:

答案 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 |
----------------------------------

附录A:将值用于简单的工会

在SPARQL 1.1中,使用值块可以替换,例如

{ ?s :p1 :o1 }
union 
{ ?s :p2 :o2 }

values (?p ?o) {
  (:p1 :o1)
  (:p2 :o2)
}
?s ?p ?o

附录B:如果您不能使用

这是使用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