![](/img/trans.png)
[英]About UNION and FILTER NOT EXISTS in SPARQL (OpenRDF 2.8.0)
[英]UNION case containing FILTER NOT EXISTS and OPTIONAL doesn't produce results?
我有一个选择一些项目的查询。 如果这些项属于特定类(: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.