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:John
Just 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 } 5
We 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, 1
Actually, 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, 1
No 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, 1
Now 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