如何确定主题是否为X Y Z或无类型

时间:2014-03-09 22:30:46

标签: rdf sparql

在我尝试之前,这个问题对我来说似乎很容易......但我也可能只是错误地思考问题。

假设我们已经从dbpedia中任意获得了100个主题。

SELECT ?s
WHERE {
  ?s ?p ?o .
}
LIMIT 100

我想要做的是添加一个列,说明它们是Person,Place还是SomeOtherType,如果没有,则为“null”。

所以,我尝试过几种方法:

  1. 使用rdf:typeVALUES

    SELECT ?s ?ppt
    WHERE {
      ?s rdf:type ?ppt .
      VALUES ?ppt {
        dbpedia-owl:Person
        dbpedia-owl:Place
        dbpedia-owl:SomeOtherType
      }
    }
    

    但是,这只是获得具有该值的主题列表,并且不一定回答它们是三种类型中的哪一种的问题(即,如果我有1个主语,代替?s,我不能只将VALUES { ... }块添加到针对该1个主题的查询中,因为如果它不是三个中的任何一个,那么将返回零结果。

  2. 我可以BIND ( IF ... ELSE ... etc ) AS ?ppt,但这似乎有点奇怪。

  3. 那么,我应该使用哪些查询函数来确定属于哪三种(四,如果算上“null”)类型中的哪一种,如果有的话?

1 个答案:

答案 0 :(得分:1)

我认为bind( if(...), ..., ...)的解决方案在这里有意义。这并不奇怪。假设您有这样的数据,其中:A:B是感兴趣的类型。

@prefix : <http://stackoverflow.com/q/22289078/1281433/> .

:i1 :name "i1" . # no type
:i2 a :A .       
:i3 a :B .       
:i4 a :A, :B .   
:i5 a :C .       
:i6 a :B, :C .

我故意添加了一些角落案例以澄清会发生什么。由于:i1根本没有类型,因此我们不会在结果中看到它。由于:i2:i3每个都有一个“感兴趣的类型”,因此它们每个都会出现在结果中一次。 :i4两种类型的兴趣,因此它会在结果中出现两次,每种感兴趣的类型一次。 :i5没有兴趣类型,因此它将显示为空类型(我使用了未绑定的变量,在answers.sematicweb.com问答中讨论的技术,Binding a variable only when another is non-blank?)。 :i6有一种兴趣和不感兴趣的类型,因此它会以感兴趣的类型出现一次,并且一次出现空白值。

prefix : <http://stackoverflow.com/q/22289078/1281433/>

select ?i ?type where { 
  ?i a ?_type . 
  bind( if( ?_type in (:A, :B), ?_type, ?noType ) as ?type )
}
--------------
| i   | type |
==============
| :i2 | :A   |
| :i3 | :B   |
| :i4 | :A   |
| :i4 | :B   |
| :i5 |      |
| :i6 |      |
| :i6 | :B   |
--------------