2

我有一个简单的 SPARQL 查询:

SELECT DISTINCT ?class1 ?class2
    WHERE {
        ?class1 :child ?attribute1 .
        ?class2 :child ?attribute2 .
        ?attribute1 :objectName ?name1 .
        ?attribute2 :objectName ?name2 .
        FILTER (?name1 = ?name2)
    }

在这些“类”之一可以有多个子级的 RDF 图中。我想要做的是,找到重复的类,其中重复意味着一个类中的所有孩子(由 objectName 标识)也在另一个类中。

它的作用是,返回每个班级也至少有一个孩子存在于另一个班级。

所以我正在寻找对每个班级的所有孩子进行某种迭代,但我还没有找到方法。如果有人可以提供帮助,那就太好了。

谢谢

4

2 回答 2

2

请注意,SPARQL 是一种声明性语言,而不是命令性语言,因此没有迭代事物的概念。您可以在 RDF 存储中的 API 中做到这一点,但至少在理论上,用 SPARQL 表达它会更有效。

我认为您需要做的是找到所有类的组合,并减去一些 objectName 不同的组合。

以下是完全未经测试的!

SELECT DISTINCT ?class1 ?class2
WHERE {
   ?class1 :child ?attribute1 .
   ?class2 :child ?attribute2 .
   MINUS {
      ?attribute1 :objectName ?name1 .
      ?attribute2 :objectName ?name2 .
      FILTER (?name1 != ?name2 && ?attribute1 = ?attribute2 )
   }
}

正确的可能性很小:) 但它应该会给您一些启发。

于 2013-07-03T10:57:57.063 回答
1

这是一些包含四个类的示例数据。第一类和第二类包含名称为“name1”和“name2”的孩子。第三类包含“name1”和“name3”,第四类包含“name3”和“name4”。第五类包含第四类的所有孩子,以及“name5”。所以,第一类和第二类是等价的,第四类是第五类的子类。

@prefix : <http://example.org/> .

:class1 :child [ :objectName "name1" ] , 
               [ :objectName "name2" ] .

:class2 :child [ :objectName "name2" ] ,
               [ :objectName "name1" ] .

:class3 :child [ :objectName "name1" ] ,
               [ :objectName "name3" ] .

:class4 :child [ :objectName "name3" ] , 
               [ :objectName "name4" ] .

:class5 :child [ :objectName "name3" ] , 
               [ :objectName "name4" ] ,
               [ :objectName "name5" ] .

您的描述听起来好像您实际上是在寻找子类,因为您提到了所有子类都在另一个类中的类。因此,这个 SPARQL 查询应该负责查找子类关系:

prefix : <http://example.org/>

select distinct ?c1 ?c2 where { 
  ?c1 :child [] .
  ?c2 :child [] .
  NOT EXISTS { ?c1 :child [ :objectName ?name ] .
               NOT EXISTS { ?c2 :child [ :objectName ?name ] } }
  FILTER( !sameTerm( ?c1, ?c2 ) )
}

嵌套NOT EXIST模式确保我们选择的唯一类是这样的,即有一个NOT EXIST元素?c1在. 也就是说,我们拒绝任何有一个元素 in而不是 in的集合对;我们拒绝任何不是的子集的对,所以我们只保留那些的子集的对。过滤器删除了琐碎的对,因为一切都将是其自身的子集。使用 Jena 的命令行 ARQ 工具​​,我们得到以下结果:NOT EXIST?c2?c1?c2?c1,?c2?c1?c2?c1 ?c2sameTerm?c,?c

$ arq --data data.n3 --query query.sparql
---------------------
| c1      | c2      |
=====================
| :class4 | :class5 |
| :class2 | :class1 |
| :class1 | :class2 |
---------------------

正如预期的那样,:class1并且:class2每个都是另一个的子集,并且:class4是 的子集:class5

如果您想要等效的类,只需一秒钟NOT EXISTS即可确保它?c2也是以下的子集?c1

prefix : <http://example.org/>

select distinct ?c1 ?c2 where { 
  ?c1 :child [] .
  ?c2 :child [] .
  NOT EXISTS { ?c1 :child [ :objectName ?name ] .
               NOT EXISTS { ?c2 :child [ :objectName ?name ] } }
  NOT EXISTS { ?c2 :child [ :objectName ?name ] .
               NOT EXISTS { ?c1 :child [ :objectName ?name ] } }
  FILTER( !sameTerm( ?c1, ?c2 ) )
}

通过这个查询,我们得到了:class1:class2

$ arq --data data.n3 --query query.sparql
---------------------
| c1      | c2      |
=====================
| :class2 | :class1 |
| :class1 | :class2 |
---------------------
于 2013-07-03T19:12:45.863 回答