I have a query that selects some items. If these items belong to a specific class (:UserSuitability), then I need to check if the user is also from the same class. There are four possible scenarios:
- The item is from a class that is rdfs:subClassOf :UserSuitability, and the user is also from the same class. Then check if the item contains a value for hasSuitabilityValue and assign it to the variable ?suitabilityValue.
- The item is from a class that is rdfs:subClassOf :UserSuitability, but the user is not, then check if the item contains a value for hasSuitabilityNotValue and assign it to the variable ?suitabilityValue.
- The item is not from a class that is rdfs:subClassOf: UserSuitability, then assign 1 to the variable ?suitabilityValue.
- The item is not from a class that is rdfs:subClassOf:UserSuitability, and neither is the user. In this case, do nothing.
My query so far, and the data to test it with are provided below. Note that :item1 in the data should match the left hand side of the union, while :item2 should match the right hand side. It seems that the right hand side never matches.
Data
@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 .
Query
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)
}
}
}