I've some RDF data which looks something like this:
WatchObject -subclassOf-> Accessory
BagObject -subclassOf-> Accessory
Person -hasAccessory-> Accessory
Where WatchObject and BagObject are both subclasses of "Accessory", which has the relation has(is)Accessory(of) with Person.
I would like to query it now to get a persons watches and bags in seperate variables. So I thought of something like:
SELECT DISTINCT ?person ?watch ?bag
WHERE {
?person rdf:type x:Person .
?person x:hasAccessory ?bag^^x:BagObject .
?person x:hasAccessory ?watch^^x:WatchObject .
}
Is it possible to express something like this in a SPARQL query? Another question would be if it's reasonable to model my data like this, or would it be better to add two more ObjectProperties like this?
WatchObject -subclassOf-> Accessory
BagObject -subclassOf-> Accessory
Person -hasAccessory-> Accessory
Person -hasWatch-> WatchObject
Person -hasBag-> BagObject
You just need to add triples specifying a type of the ?bag and ?watch variables, just like you specified a type for the ?person variable:
SELECT DISTINCT ?person ?watch ?bag {
?person a x:Person .
?person x:hasAccessory ?bag .
?bag a x:BagObject .
?person x:hasAccessory ?watch .
?watch a x:WatchObject .
}
Note that that will get you the cross product of bags and watches; i.e., you'll get each combination of a person's bags and watches. Also, it requires that the person have at least one bag and at least one watch, otherwise the query won't match. You might look into optional to see how to make these optional.
Another question would be if it's reasonable to model my data like this, or would it be better to add two more ObjectProperties like this?
WatchObject -subclassOf-> Accessory BagObject -subclassOf-> Accessory Person -hasAccessory-> Accessory Person -hasWatch-> WatchObject Person -hasBag-> BagObject
You could do this, too. If you do, then it might also be good to add the triples:
hasWatch rdfs:subPropertyOf hasAccessory
hasBag rdfs:subPropertyOf hasAccessory
Then, if you have inference enabled, or you adjust your query a little bit, then you can still retrieve things with just the one hasAccessory property.