select SPARQL 查询的否定

select the negative of a SPARQL query

可以 select sparql 查询的 "negative" 吗?

例如,考虑以下 RDF 数据、查询和期望的结果:

知识库:

@prefix gr:<http://purl.org/goodrelations/v1#>.
@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#>.

:prod_A :hasProp :propA.
:prod_B :hasProp :propB.
   :propB rdfs:label "Hello".
:prod_C :hasProp :propC.
:prod_D :hasProp :propD.

虚构查询:

PREFIX gr:<http://purl.org/goodrelations/v1#>

SELECT ?prod WHERE 
   { !( 
      ?prod ?p ?o.
      ?o ?p2 ?o2.
   ) }

理想结果:

| ?prod   |
|---------|
| :prod_A | 
| :prod_C | 
| :prod_D | 

有办法吗? (我需要它 delete

我认为 MINUS 是您要找的:

PREFIX gr:<http://purl.org/goodrelations/v1#>

SELECT ?prod WHERE 
{
  ?prod ?p ?o.
  MINUS { ?o ?p2 ?o2 }
}

它获取左侧 (?prod ?p ?o) 匹配的内容,并删除与 MINUS 模式匹配的项目对应的所有内容。

请注意,这不会给出您想要的答案,因为 ?prod ?p ?o 模式匹配所有内容,包括您对结果不感兴趣的链接 属性 (:propB rdfs:label "Hello")

要获得所需的答案,您需要使查询的第一部分更具体,如下所示:

PREFIX :<http://example.org/>
PREFIX gr:<http://purl.org/goodrelations/v1#>

SELECT ?prod WHERE 
{
  ?prod :hasProp ?o.
  MINUS { ?o ?p2 ?o2 }
}

在这里,我将 ?p 变量更改为 :hasProp 常量。通过这个查询,我得到了你想要的答案。

NB - 你没有在你的例子中定义空前缀所以我发明了一个使查询有效所以我可以测试它是否有效

另一种方法是使用FILTER NOT EXISTS

SELECT ?prod WHERE 
{
  ?prod :hasProp ?o.
  FILTER NOT EXISTS { ?o rdfs:label "Hello". }
}

第一个 ?prod :hasProp ?o. 然后检查 ?o 是否导致 ?o rdfs:label "Hello" 匹配。使用您认为最容易理解的形式。