【问题标题】:Conditional subquery in SPIN function (SPARQL)SPIN 函数中的条件子查询 (SPARQL)
【发布时间】:2015-10-12 20:49:14
【问题描述】:

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

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

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

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

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

我已经尝试过使用FILTERBOUND 函数,但我不知道如何获得正确的行为。当?subj 未绑定时,如何从查询中删除UNION 子句之一?

更新

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

【问题讨论】:

    标签: sparql topbraid-composer spin-rdf


    【解决方案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,您希望返回什么?此外,您的这个子图没有将填充图表的断言,因此不会返回任何内容。


    拉尔夫

    【讨论】:

    • Ralph,我更新了问题中的魔法属性定义,添加了示例代码中缺少的术语。意图是,“给定某个值 ?subj,对于所有 Rule 资源,查找具有 rule.someProp == subj OR rule.someProp == null 的规则(属性未定义)。如果输入值 ?subj 为 null,则返回只有 rule.someProp == null 的规则。”
    • 我尝试使用“FILTER(BOUND(?property))”之类的东西,但我发现 ?property 被绑定是因为它下面的语句在同一个块中,所以它没有t 按照我想要的方式过滤掉结果。
    【解决方案2】:

    诀窍是,我需要使用与作为参数传入的变量不同 的变量来执行 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)) .
    }
    

    【讨论】:

      【解决方案3】:

      另一种方法是使用 COALESCE:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多