1

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

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

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未绑定(即,我将其设置为UNDEFVALUES块中),则上述查询会变得疯狂并返回所有内容。

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

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

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

更新

修改了第一个查询以添加VALUES块。
添加了缺失?result a :Rule .的语句。
更正?someProp:someProp.

4

3 回答 3

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 未定义,以及 ?result 和 ?anyValue,你期待什么回来?此外,您的这个子图没有任何断言会填充该图,因此不会返回任何内容。


拉尔夫

于 2015-10-13T19:48:40.837 回答
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)) .
}
于 2015-10-13T20:39:40.133 回答
1

另一种方法是使用 COALESCE:

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

...这避免了子选择并简单地过滤以仅包含 ?result 匹配项 where '?value = ?subj',如果该子句失败,则 !bound() 子句确保没有 :someProp 属性的匹配项是也包括在内。

于 2016-02-18T04:24:06.453 回答