1. Advanced RDF and SPARQL
1.1. Introduction
We have Morrel, Max and Sasha being dogs, Sheeba and Query are cats, Picca is still a parrot, Fred and John are contacts. Fred claims that John is his friend. I changed the ontology to allow friendships between the animals too: Sasha claims that Morrel and Max are her friends. Sheeba claims Query is her friend. John bought Query. Fred being inspired by John decided to also get some pets: Morrel, Sasha and Sheeba.
1.2. Ontology
You can find the ontology here.
Let’s put this story in Turtle:
<test:Picca> a test:Parrot, test:Pet ;
test:name "Picca" .
<test:Max> a test:Dog, test:Pet ;
test:name "Max" .
<test:Morrel> a test:Dog, test:Pet ;
test:name "Morrel" ;
test:hasFriend <test:Max> .
<test:Sasha> a test:Dog, test:Pet ;
test:name "Sasha" ;
test:hasFriend <test:Morrel> ;
test:hasFriend <test:Max> .
<test:Sheeba> a test:Cat, test:Pet ;
test:name "Sheeba" ;
test:hasFriend <test:Query> .
<test:Query> a test:Cat, test:Pet ;
test:name "Query" .
<test:John> a test:Contact ;
test:owns <test:Max> ;
test:owns <test:Picca> ;
test:owns <test:Query> ;
test:name "John" .
<test:Fred> a test:Contact ;
test:hasFriend <test:John> ;
test:name "Fred" ;
test:owns <test:Morrel> ;
test:owns <test:Sasha> ;
test:owns <test:Sheeba> .
1.3. Querytime!
Let’s first start with all friend relationships:
SELECT ?subject ?friend
WHERE { ?subject test:hasFriend ?friend }
test:Morrel, test:Max
test:Sasha, test:Morrel
test:Sasha, test:Max
test:Sheeba, test:Query
test:Fred, test:JohnJust counting these is pretty simple. In SPARQL all selectable fields must have a variable name, so we add the “as c” here.
SELECT COUNT (?friend) AS c
WHERE { ?subject test:hasFriend ?friend }
5We counted friend relationships, of course. Let’s say we want to count how many friends each subject has. This is a more interesting query than the previous one.
SELECT ?subject COUNT (?friend) AS c
WHERE { ?subject test:hasFriend ?friend }
GROUP BY ?subject
test:Fred, 1
test:Morrel, 1
test:Sasha, 2
test:Sheeba, 1Actually, we’re only interested in the human friends:
SELECT ?subject COUNT (?friend) AS c
WHERE { ?subject test:hasFriend ?friend .
?friend a test:Contact
} GROUP BY ?subject
test:Fred, 1No no, we are only interested in friends that are either cats or dogs:
SELECT ?subject COUNT (?friend) AS c
WHERE { ?subject test:hasFriend ?friend .
?friend a ?type .
FILTER ( ?type = test:Dog || ?type = test:Cat)
} GROUP BY ?subject"
test:Morrel, 1
test:Sasha, 2
test:Sheeba, 1Now we are only interested in friends that are either a cat or a dog, but whose name starts with a ‘S’.
SELECT ?subject COUNT (?friend) as c
WHERE { ?subject test:hasFriend ?friend ;
test:name ?n .
?friend a ?type .
FILTER ( ?type = test:Dog || ?type = test:Cat) .
FILTER REGEX (?n, '^S', 'i')
} GROUP BY ?subject
test:Sasha, 2
test:Sheeba, 1