SPARQL查询中的"or"

47

我不太明白为什么在SPARQL中他们没有实现基本的逻辑运算符。然而,在大多数情况下,可以通过多种方式获得相同的结果。

这个问题的目的是为了快速参考可以替代“或”语句的可能方法。

以下是我能想到的:

1)UNION

例如:

SELECT * WHERE
{  { ?s :propA ?o } UNION { ?s :propB ?o }  }

由于它可能变得非常冗长,因此通常不太合适

SELECT * WHERE { 
    { GRAPH ?g {?s ?p ?o. ?o ?pp ?data1}} UNION 
    { GRAPH ?g {?s ?p ?o. ?o ?pp ?data2}}
} 

无法正常工作

SELECT * WHERE { 
    GRAPH ?g {
       ?s ?p ?o. 
       {?o ?pp ?data1} UNION 
       {?o ?pp ?data2} 
    }
 }

(至少不会使用Stardog)

2)FILTER

例如:

SELECT * WHERE
    { 
        ?s ?p ?o.
        FILTER (?p = :propA || ?p = :propB )
    }

还有其他想法吗?


抱歉,当您说第一个查询“不像”第二个查询时,您的意思是什么?您是否期望这两个查询执行完全相同的操作? - Jeen Broekstra
如果UNION的作用类似于逻辑OR,那么这两个查询将产生相同的结果,但显然它们并没有。很抱歉我无法恰当地解释自己,我是SPARQL新手,同时英语也不是我的母语,非常感谢您的理解和时间。 - ffa
1
@ffa 我们有点跑题了,但你似乎误解了UNION与逻辑OR的不同之处。它们在语义上是完全相同的。然而,这两个查询不同的原因仅仅是作用域的不同。第一个查询是((?s ?p ?o ?g) AND (?o ?pp ?data1 ?g)) OR ((?s ?p ?o ?g) AND (?o ?pp ?data2 ?g)),第二个查询是(?s ?p ?o ?g) AND ((?o ?pp ?data1 ?g) OR (?o ?pp ?data2 ?g)) - Jeen Broekstra
1
不用担心你的英语,没问题的。如果我没听懂你说的话,我会请你解释一下(希望你也能这样对我):) - Jeen Broekstra
2个回答

61

我不太确定你为什么说SPARQL没有提供“基本逻辑运算符”,因为你自己的示例清楚地表明它提供了:作为FILTER条件的逻辑或(||)和逻辑与(&&),以及使用UNION的析取图模式(当然,合取图模式不需要特殊的语法)。

还有其他类似OR的结构的变体也是可能的。对于形式为“这个特定值必须是这些可能性之一”的查询,您可以使用集合成员运算符IN:

SELECT * 
WHERE { 
    ?s ?p ?o.
    FILTER (?p IN (:propA, :propB, :propC ) )
}

您还可以使用VALUES子句来实现这种模式:

SELECT * 
WHERE {
    VALUES ?p { :propA :propB :propC } 
    ?s ?p ?o.
}

更新 我忘记了一个,或许是最简单的方法。对于像你这样寻找几个属性名称的查询,你也可以使用属性路径表达式,例如:

SELECT * 
WHERE {
    ?s :propA|:propB|:propC ?o.
}

1
我的意思是,你只能在FILTER条件中使用基本逻辑运算符。在我(有限的)经验中,更全面的实现在许多情况下都会很方便。UNION语句通常不是一个选项,因为你不能嵌套它。无论如何,感谢您的宝贵贡献。 - ffa
是的,但例如 SELECT * WHERE{ { GRAPH ?g {?s ?p ?o. ?o ?pp ?data1} UNION { GRAPH ?g {?s ?p ?o. ?o ?pp ?data2} } 不像 SELECT * WHERE{ { GRAPH ?g {?s ?p ?o. {?o ?pp ?data1} UNION { ?o ?pp ?data2} } (至少在Stardog中)有效。 - ffa
1
@JeenBroekstra:对于对象也起作用吗?例如? a a:object1 |:object2。我实际上已经尝试过了,但它没有起作用。但是我可能做错了什么!!! - msc87
3
@msc87,不,属性路径表达式仅适用于属性。对于对象,您将需要使用其他构造之一。 - Jeen Broekstra
1
感谢您的解释 - 我已经尝试了所有三种方法,并发现了一些有趣的性能问题。例如,使用Apache Jena时,属性路径变量明显是最慢的。您有任何提示吗?为什么会这样? - Rok
显示剩余3条评论

6

如果您想追踪哪个谓词导致了哪个对象,那么这是“OR”通用解决方案:

SELECT DISTINCT ?s ?o1 ?o2 
WHERE {
  {
     ?s p1 ?o1 .
     OPTIONAL
     {
        ?s p2 ?o2 .
     }
  } 
  UNION 
  {
     ?s p2 ?o2 .
     OPTIONAL
     {
        ?s p1 ?o1 .
     }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接