繁体   English   中英

包含FILTER NOT EXISTS和OPTIONAL的UNION案例不会产生结果?

[英]UNION case containing FILTER NOT EXISTS and OPTIONAL doesn't produce results?

我有一个选择一些项目的查询。 如果这些项属于特定类(:UserSuitability),那么我需要检查用户是否也来自同一个类。 有四种可能的情况:

  1. 该项来自一个类rdfs:subClassOf:UserSuitability,并且该用户也来自同一个类。 然后检查该项是否包含hasSuitabilityValue的值,并将其分配给变量?suitabilityValue。
  2. 该项来自一个类rdfs:subClassOf:UserSuitability,但用户不是,然后检查该项是否包含hasSuitabilityNotValue的值并将其分配给变量?suitabilityValue。
  3. 该项不是来自rdfs:subClassOf:UserSuitability的类,然后将1分配给变量?suitabilityValue。
    1. 该项不是来自rdfs:subClassOf:UserSuitability的类,也不是用户。 在这种情况下,什么都不做。

到目前为止,我的查询以及测试它的数据如下所示。 请注意:数据中的item1应与union的左侧匹配,而:item2应与右侧匹配。 似乎右手边永远不会匹配。

数据

@prefix : <http://www.semanticrecommender.com/rs#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

:user1 a :class1 .
:user1 :likes :item1 .
:user1 :likes :item2 .
:class1 rdfs:subClassOf :UserSuitability .
:item1 a :class1 .
:item1 :hasSuitabilityWeight 1.5 .
:item1 :hasNotSuitabilityWeight 0.5 .
:item2 a :class2 .
:class2 rdfs:subClassOf :UserSuitability .

询问

prefix : <http://www.semanticrecommender.com/rs#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?item ?suitabilityValue where
{
  values ?user {:user1}
  ?user :likes ?item

  optional{
    #-- check if the item is from a class that is
    #-- rdfs:subClassOf :UserSuitability
    ?item a ?suitabilityClass.
    ?suitabilityClass rdfs:subClassOf :UserSuitability.
    {
      #-- if the user is also from the same class
      ?user a ?suitabilityClass
        optional{
        #-- check if the item has a value for :hasSuitabilityWeight
        ?item :hasSuitabilityWeight ?suitabilityValueOptional.
      }
      #-- if it does, assign it to the variable
      #-- ?suitabilityValue, otherwise, assign 1
      #-- to the variable suitabilityValue
      bind(if(bound(?suitabilityValueOptional), ?suitabilityValueOptional, 1) as ?suitabilityValue)

    }
    union
    {
      #-- if the user is not from the same class
      filter not exists {?user a ?suitabilityClass}
      optional{
        #-- if the item has a value to hasNotSuitabilityWeight
        ?item :hasNotSuitabilityWeight ?suitabilityNotValueOptional.
      }
      #-- assign it to suitabilityValue, otherwise, assign 0
      bind(if(bound(?suitabilityNotValueOptional), ?suitabilityNotValueOptional, 0) as ?suitabilityValue)
    }
  }
}

所以,我试图从头开始重新创建这个问题,最后得到的数据与你的非常相似,虽然有点简单。 这是我最终使用的数据,这让我可以避免对类是否真正适合的过滤。

@prefix : <urn:ex:>

:user a :A ;
      :likes :i , :j .

:i a :A ;
   :hasValueYes 1 ;
   :hasValueNo  2 .

:j a :B .

现在,这是与您相同的查询; 它只获得两个项目之一的结果,即使它看起来像另一个应该匹配。 我将在后面解释一条注释行。

prefix : <urn:ex:>

select ?item ?value {
  values ?user { :user }

  ?user :likes ?item .
  ?item a ?itemClass .

  {
    ?user a ?itemClass
    optional {
      ?item :hasValueYes ?valueYes
    }
    bind(if(bound(?valueYes), ?valueYes, "default yes value") as ?value)
  }
  union
  {
    #-- ?item ?anyP ?anyO   # (***)
    filter not exists { ?user a ?itemClass }
    optional {
      ?item :hasValueNo ?valueNo
    }
    bind(if(bound(?valueNo), ?valueNo, "default no value") as ?value)
  }
}  
----------------
| item | value |
================
| :i   | 1     |
----------------

现在,该查询中有一条注释行:

#-- ?item ?anyP ?anyO   # (***)

如果您取消注释该行,您将获得您期望的结果:

-----------------------------
| item | value              |
=============================
| :i   | 1                  |
| :j   | "default no value" |
-----------------------------

认为这里发生的是在第二个可选的情况下,因为没有引入绑定的三重模式(因为可选的不匹配),所以联合的那一侧不会被包含, 即使 绑定会引入如果允许一方匹配,则会有一些绑定。 通过添加模式:

?item ?anyP ?anyO

在查询时,至少还有东西,这将在工会 ,在该点块的其余部分被包含的那部分匹配。 我使用?anyP?anyO来强调它是随意的,但是因为你已经知道?项是一个?itemClass ,你可以再次包含那个三元组,即?item a?itemClass

所以,在你的情况下,如果你只是添加

?user :likes ?item

到右手联合块,你会得到你期望的结果:

-----------------------------
| item   | suitabilityValue |
=============================
| :item2 | 0                |
| :item1 | 1.5              |
-----------------------------

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM