【问题标题】:UNION case containing FILTER NOT EXISTS and OPTIONAL doesn't produce results?包含 FILTER NOT EXISTS 和 OPTIONAL 的 UNION 案例不会产生结果?
【发布时间】:2016-03-14 17:59:30
【问题描述】:

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

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

到目前为止,我的查询以及用于测试它的数据如下所示。请注意,数据中的 :item1 应匹配并集的左侧,而 :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)
    }
  }
}

【问题讨论】:

  • 抱歉关门了。现已重新开放。
  • 哇哦..这很有趣,你会喜欢的
  • @JoshuaTaylor 感谢您的回答,然后重新打开,:) 我在购物,我会在家里再次检查一次
  • 嗯,我也投了最后的结束票,所以这真的只是在弥补我的错误。不过,您会在我的回答中看到,您可以使用更简单的测试用例重现该问题;您提供的查询(以及其中的一些格式)确实使您很容易对绑定表单的位置感到困惑。也就是说,这一个非常奇怪的问题,我也花了一段时间才知道它是什么。
  • 只是说明确保您的示例不仅完整(且可验证)而且最小 的重要性:) 无论如何,发现了 Joshua。跨度>

标签: sparql rdf semantic-web owl ontology


【解决方案1】:

因此,我尝试从头开始重新创建此问题,并最终得到与您的数据非常相似的数据,尽管更简单一些。这是我最终使用的数据,它让我避免了一些关于一个类是否真的合适的过滤。

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

认为这里发生的情况是在第二种可选情况下,因为没有引入绑定的三元组模式(因为 optional 不匹配), union 的那一侧不会被包含在内,即使 bind 会引入一些绑定,如果允许该一侧匹配的话。通过添加模式:

?item ?anyP ?anyO

对于查询,在 union 的该部分中至少有 一些东西 将匹配,此时该块的其余部分将被包含在内。我使用 ?anyP?anyO 来强调它是任意的,但既然你已经知道 ?item 是一个 ?itemClass ,您可以再次包含该三元组,即 ?item a ?itemClass

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

?user :likes ?item

在右侧的 union 块中,您将获得预期的结果:

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

【讨论】:

  • 所以我是如此接近,我尝试了你的,它完全按照需要工作,一如既往地感谢。只有一件事,您假设?item 总是有一个类?itemClass,这是不必要的,我将它们全部放在一个可选中,并在可选的之后绑定:)。再次感谢,我很感激
  • @AniaDavid 是的,在 my 示例数据中,项目总是有一个类,所以这是一个安全的行,可以保证匹配。正如我在回答中所说,在 您的 情况下,安全线将是 ?user :likes ?item,因为您(从外部查询)知道它将始终匹配。
  • 这就是我实际添加的?user :likes ?item,再次感谢,你就是那个
猜你喜欢
  • 2015-10-30
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-06
  • 2018-11-15
  • 2013-11-18
  • 1970-01-01
相关资源
最近更新 更多