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

时间:2016-03-14 17:59:31

标签: sparql rdf semantic-web owl ontology

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

  1. 该项来自rdfs:subClassOf:UserSuitability的类,用户也来自同一个类。然后检查该项是否包含hasSuitabilityValue的值并将其分配给变量?suitabilityValue。
  2. 该项来自一个类rdfs:subClassOf:UserSuitability,但用户不是,然后检查该项是否包含hasSuitabilityNotValue的值并将其分配给变量?suitabilityValue。
  3. 该项不是来自rdfs:subClassOf:UserSuitability的类,然后将1分配给变量?suitabilityValue。
    1. 该项不是来自rdfs:subClassOf:UserSuitability的类,也不是用户。在这种情况下,什么都不做。
  4. 到目前为止,我的查询以及要测试的数据如下所示。请注意:数据中的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)
        }
      }
    }
    

1 个答案:

答案 0 :(得分:3)

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

@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" |
-----------------------------

认为这里发生的是第二种可选情况,因为没有引入绑定的三重模式(因为可选不会&# 39; t匹配),联合的那一方没有包含在内,即使 bind 也会引入一些绑定一方被允许匹配。通过添加模式:

?item ?anyP ?anyO

对于查询,至少某些将匹配联合的那一部分,此时将包含其余部分。我使用?anyP ?anyO 来强调它是随意的,但是因为你已经知道?item 是< strong>?itemClass ,您可以再次包含该三元组,即?item a?itemClass

因此,在您的情况下,如果您只是添加

?user :likes ?item

右侧联盟阻止,您将获得您期望的结果:

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