为什么可选绑定不起作用

Why is the optional binding not working

这是一个关于为什么我的代码不起作用的问题,而不是关于如何做某事的问题,这就是我没有这样做的原因给你一个数据,如果你要,我可以给你,但是数据会是我的比较小ontology.

这是我的代码

OPTIONAL
      { 

    VALUES ?user { rs:ania }
        ?userContext  rdf:type       rs:UserContext ;
                  rs:appliedOnItems  ?itemClass ;
                  rs:appliedOnUsers  ?userClass .

        ?item  rdf:type  ?itemClass .

        OPTIONAL
          { ?userContext  rs:hasWeightIfContextMatched  ?weightMatched }
        OPTIONAL
          { ?userContext  rs:hasWeightIfContextDoesNotMatch  ?weightNotMatched }
        OPTIONAL
          { ?userContext  rs:doNotRecommendInCaseNotMatch  true
            BIND(1 AS ?skip_)
          }
      bind(if (bound(?skip_) && (not EXISTS {?user a ?userClass}) , ?skip_, 0) as ?skip1)


    values (?defaultUserMatched ?defaultUserNotMatched) {(1 0.5)}
        BIND(if(EXISTS { ?user  rdf:type  ?userClass }, coalesce(?weightMatched, ?defaultUserMatched), coalesce(?weightNotMatched, ?defaultUserNotMatched)) AS ?weight)


      }
    values ?defaultNoUserContext {1}
    BIND(if(bound(?skip1), ?skip1, 0) as ?skip)
    BIND(if(bound(?weight), ?weight, ?defaultNoUserContext) AS ?userContextWeight)

  }

这段代码只是我真实查询中的一个块,还有另一个块带来了 ?item 变量。

如您所见,我的代码有 ?item rdf:type ?itemClass ,但是 ?item 的绑定之一不是来自 ?itemClass 的类型,因此整个可选的将不会执行(为此binding),所以当我们走出optional的时候,就有了这一行

BIND(if(bound(?weight), ?weight, ?defaultNoUserContext) AS ?userContextWeight)

if 部分将给出 false,因此 ?userContextWeight 应该绑定到 ?defaultNoUserContext。但是,我的代码不会为这些项目产生任何东西(根本没有任何价值)。你知道为什么吗?

再次,如果您需要数据,我非常欢迎您提供,谢谢

更新

现在我看清楚了,我想要的是:

即使该项目不属于 ?itemClass,我也需要为 ?userContextWeight 提供默认值。

看更新

 OPTIONAL
      { 
     VALUES ?user { rs:ania }

        ?userContext  rdf:type       rs:UserContext ;
                  rs:appliedOnItems  ?itemClass ;
                  rs:appliedOnUsers  ?userClass .

    bind (if (  exists {?item  rdf:type  ?itemClass .}, true , false) as ?doesItemBelongToUserContextItemClass)

    OPTIONAL
          { ?userContext  rs:hasWeightIfContextMatched  ?weightMatched }
        OPTIONAL
          { ?userContext  rs:hasWeightIfContextDoesNotMatch  ?weightNotMatched }
        OPTIONAL
          { ?userContext  rs:doNotRecommendInCaseNotMatch  true
            BIND(1 AS ?skip_)
          }
      bind(if (bound(?skip_) && (not EXISTS {?user a ?userClass}) , ?skip_, 0) as ?skip1)


    values (?defaultUserMatched ?defaultUserNotMatched) {(1 0.5)}
        BIND(if(EXISTS { ?user  rdf:type  ?userClass }, coalesce(?weightMatched, ?defaultUserMatched), coalesce(?weightNotMatched, ?defaultUserNotMatched)) AS ?weight)
      }
    values ?defaultNoUserContext {1}
    BIND(if(bound(?skip1), ?skip1, 0) as ?skip)

  BIND( if ( !?doesItemBelongToUserContextItemClass , ?defaultNoUserContext ,if(bound(?weight), ?weight, ?defaultNoUserContext)) AS ?userContextWeight)

  }

在更新中,我检查该项目是否属于 class 或不使用此 bind

 bind (if (  exists {?item  rdf:type  ?itemClass .}, true , false) as ?doesItemBelongToUserContextItemClass)

然后在 optional 之外,我这样做

BIND( if ( !?doesItemBelongToUserContextItemClass , ?defaultNoUserContext ,if(bound(?weight), ?weight, ?defaultNoUserContext)) AS ?userContextWeight)

我的问题是当项目不属于 class 时 ?userContextWeight 的值是 ?weightNotMatched,但它应该是 ?defaultNoUserContext(再看请最后绑定)

有什么想法吗?

更新 2

by !?doesItemBelongToUserContextItemClass 我的意思是我们在代数中学习的普通布尔值 not ,也许这里和那里不一样?这可能是问题所在?

更新 3

我看到了这个

 bind (if ( exists {?item  a  ?itemClass }, true , false) as ?doesItemBelongToUserContextItemClass)

总是给 truedoesItemBelongToUserContextItemClass 即使那是不正确的,对于特定的 item,它不是来自 itemClass.

现在我确定问题出在这里,因为我打印了 doesItemBelongToUserContextItemClass 的值并且它始终为真 但那是不正确的,我们是关闭,所以只需解决这个问题就可以解决问题

你的查询太大了,我很难理解它,但我最好的猜测是你 运行 处于 存在的情况 表达式没有绑定所有你需要的变量来测试你想要它测试的东西。这里有一些非常简单的数据:

@prefix : <urn:ex:>

:s a :D .
:t a :E .

现在,看看这个查询和结果:

prefix : <urn:ex:>

select * where {
  #-- Find an individual ?a and (one of)
  #-- the classes that it belongs to.
  ?a a ?aClass .

  optional {
    #-- Find an individual ?b and (one of)
    #-- the classes that it belongs to.
    ?b a ?bClass .

    #-- And bind ?isCommonClass to true or
    #-- false, to indicate whether ?b is
    #-- also an element of ?aClass.
    bind(exists{?b a ?aClass} as ?isCommonClass)
  }
}
---------------------------------------------
| a  | aClass | b  | bClass | isCommonClass |
=============================================
| :s | :D     | :s | :D     | true          |
| :s | :D     | :t | :E     | true          |
| :t | :E     | :s | :D     | true          |
| :t | :E     | :t | :E     | true          |
---------------------------------------------

?isCommonClass 始终为真,即使当 ?a 和 ?b 相同时看起来应该为真,否则为假。我 认为 这里发生的事情是 bind 在 ?b 或 ?aClass 尚未设置的上下文中被评估,所以exists 实际上是在检查更一般的东西。我们可以通过将 bind 移动到 optional:

之外来测试它
select * where {
  ?a a ?aClass .

  optional {
    ?b a ?bClass .
  }

  bind(exists{?b a ?aClass} as ?isCommonClass)
}
---------------------------------------------
| a  | aClass | b  | bClass | isCommonClass |
=============================================
| :s | :D     | :s | :D     | true          |
| :s | :D     | :t | :E     | false         |
| :t | :E     | :s | :D     | false         |
| :t | :E     | :t | :E     | true          |
---------------------------------------------

在这里,我们得到了预期的结果,当 ?a 和 ?b 相同时,?isCommonClass 为真。

问题中的查询片段没有提供足够的信息来确保这是正在发生的事情,而且您在评论中提供的查询太大,其他人无法检查,但这 似乎 很适合你的情况。