SPIN函数中的条件子查询(SPARQL)

时间:2015-10-12 20:49:14

标签: sparql topbraid-composer spin-rdf

如何根据变量是否绑定更改查询公式?

我正在调用这样的魔法属性:

WHERE {
    VALUES (?subj) {
        ([my bound positional parameter value goes here...])
    }
    ?subj :myMagicProperty ?result .    
}

在魔法属性中,我做了一个联盟:

?result a :Rule .
{
    ?result :someProp ?subj .
}
UNION
{
    FILTER NOT EXISTS {
        ?result :someProp ?anyValue .
    }
}

换句话说,在:someProp未定义此值 :someProp的情况下,获取所有结果。

这是棘手的部分。如果?subj未绑定(即我在UNDEF块中将其设置为VALUES),则上述查询会变为疯狂并返回所有内容。

相反,我想检查?subj是否未绑定。如果?subj未绑定,则:myMagicProperty返回以下结果:

FILTER NOT EXISTS {
    ?result ?someProp ?anyValue .
}

我已尝试使用FILTERBOUND函数,但我无法弄清楚如何获得正确的行为。如果未绑定UNION,如何从查询中删除?subj个句子之一?

更新

修改了第一个添加VALUES块的查询 添加了遗漏的?result a :Rule .声明 已将?someProp更改为:someProp

3 个答案:

答案 0 :(得分:1)

首先,我想确认一下你的意图。我想通过要求您回复以下可以在TopBraid Composer中运行的查询来做到这一点。

SELECT *
  WHERE { GRAPH <http://topbraid.org/examples/kennedys> {
    VALUES (?property) {(kennedys:firstName) (kennedys:lastName) (UNDEF)}
    { 
      FILTER(BOUND(?property) )
      ?s ?property ?result .  
    }
  UNION 
   {
     FILTER(!BOUND(?property))
     BIND("not sure what you want to do in this case" AS ?result)
    }
   }
 }

上面代码与代码的区别在于我在VALUES语句中设置了?someProp的值,而你设置了?subj。

UNIONed子图使用BOUND和!BOUND作为警卫。

在进一步提供帮助之前,我想听听您对想要构建的查询的更清楚的解释。然后我可以告诉你需要的魔法属性。

这是你需要了解更多内容的首篇文章:

这是棘手的部分。如果?subj是未绑定的(即,我在VALUES块中将其设置为UNDEF),则上述查询会变为疯狂并返回所有内容。

相反,我想检查?subj是否未绑定。如果?subj未绑定,myMagicProperty应仅返回以下结果:

FILTER NOT EXISTS {
   ?result ?someProp ?anyValue .
}*

使用?someProp undefined,以及?result和?anyValue,你还有什么期望回来?你的这个子图也没有填充图形的断言,因此不会返回任何内容。

拉​​尔夫

答案 1 :(得分:1)

诀窍是,我需要使用与作为参数传入的变量不同来使用UNION。这样,UNION操作不会导致绑定未绑定的参数。在UNION之后,我可以使用FILTER根据输入参数控制结果。

SELECT ?result
WHERE {
    ?result a :Rule .
    {
        SELECT ?rule ?value ?anyValueMatch
        WHERE {
            {
                ?rule :someProp ?value .
                BIND (false AS ?anyValueMatch) .
            }
            UNION
            {
                FILTER NOT EXISTS {
                    ?rule :someProp ?any .
                } .
                BIND (true AS ?anyValueMatch) .
            } .
        }
    } .
    FILTER ((bound(?subj) && (?value = ?subj)) || (?anyValueMatch = true)) .
}

答案 2 :(得分:1)

另一种方法是使用COALESCE:

SELECT ?result
WHERE {
   ?result a :Rule .
   OPTIONAL {
      ?result :someProp ?value .
   }
   FILTER (COALESCE(?value = ?subj, !bound(?value)))
}

...这避免了子选择,只是过滤只包含?结果匹配'?value =?subj',如果该子句失败,!bound()子句确保没有匹配的匹配: someProp属性也包括在内。