Manipulating output with FILTER, OPTIONAL and UNION

In my last blog post, I talked about working with graphs that don't have a SPARQL endpoint. In this post, I'll look at how to choose the data output from the graph using FILTER, OPTIONAL and UNION.

FILTER

The SPARQL operator FILTER allows for the data output to be limited based on some criteria. For example, you can choose to output only the literal values for a given predicate that are in a particular language.

PREFIX schema: <http://schema.org/> 
SELECT ?name
FROM <http://worldcat.org/entity/work/id/67201841>
WHERE {
?s schema:name ?name .
FILTER(langMatches(lang(?name), ”en"))
} 

Or maybe you are looking at a bibliographic record graph and only want to get the subjects that are from FAST.

PREFIX schema: <http://schema.org/> 
SELECT ?subject_name
FROM <http://www.worldcat.org/oclc/660967222>
WHERE {
?s schema:about ?about .
?about schema:name ?subject_name
FILTER regex(STR(?about), “fast”).
}

OPTIONAL

Another important operator to be aware of in SPARQL is OPTIONAL. This operator allows you to say that a particular portion of a SPARQL query is optional. If you don't use this operator and one of the criteria specified doesn't match, you will get zero results. An example of this is below.

PREFIX schema: <http://schema.org/> 
SELECT ?creator ?author
FROM <http://www.worldcat.org/oclc/660967222>
WHERE {
?s schema:creator ?creator .
?s schema:author ?author .
}

The graph in question won't return any results because it doesn't have any author predicates. To account for this, the SPARQL query should instead be:

PREFIX schema: <http://schema.org/> 
SELECT ?creator_name ?author_name
FROM <http://www.worldcat.org/oclc/660967222>
WHERE {
?s schema:creator ?creator .
?creator schema:name ?creator_name
OPTIONAL {?s schema:author ?author 
?author schema:name ?author_name} .
}

This will return a result for each match. In this case, only one result is returned.

What happens if both the predicates are present, though? The following query requests the schema:creator and schema:contributor predicates from the graph at the URI http://www.worldcat.org/oclc/660967222. 

PREFIX schema: <http://schema.org/>
SELECT ?creator_name ?contributor_name
FROM <http://www.worldcat.org/oclc/660967222>
WHERE {
?s schema:creator ?creator .
?creator schema:name ?creator_name
OPTIONAL {?s schema:contributor ?contributor . 
?contributor schema:name ?contributor_name} .
}

In this case, two results are returned, but one of the values is in the creator_name cell while the other is in the contributor_name cell. If you want the results completely merged, then you need to use UNION.

UNION

This operator is extremely useful if you want to join together the criteria from two separate WHERE statements or to join data that use two different predicates that you want to treat as the same. In our example, we are trying to treat the author name and creator name as the same.

You might think that you can simply do this using the following query.

PREFIX schema: <http://schema.org/>   
SELECT ?name  
FROM <http://www.worldcat.org/oclc/660967222>
WHERE {  
?s schema:creator ?creator .  
?creator schema:name ?name 
OPTIONAL {?s schema:contributor ?contributor . 
?contributor schema:name ?name} .  
}

Unfortunately, this query doesn't return the appropriate results. It only returns a single result rather than the desired two results. The proper query utilizes UNION to merge the results from the appropriate triples being selected.

PREFIX schema: <http://schema.org/>
SELECT ?name
FROM <http://www.worldcat.org/oclc/660967222>
WHERE {
{<http://www.worldcat.org/oclc/660967222> schema:creator ?creator.
?creator schema:name ?name }
}
UNION
{<http://www.worldcat.org/oclc/660967222> schema:contributor ?contributor.
?contributor schema:name ?name}

In this blog post, we've reviewed three new operators that can help us control the information returned from a query. In our next blog post, we'll talk about federated queries and how they can be used to access data from different datasets with distinct SPARQL endpoints.

Register for our upcoming Linked Data webinars!

  • Karen Coombs

    Karen Coombs

    Senior Product Analyst