我有一个选择一些项目的查询。如果这些项属于特定类(: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)
}
}
}
答案 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 |
-----------------------------