Ask me anything
Ithy Logo
Sign in to save

Unlock the Power of EU Data: Your Comprehensive SPARQL Journey with CELLAR

Master SPARQL from fundamentals to advanced querying on EUR-LEX's vast legal knowledge graph, CELLAR.

sparql-cellar-eurlex-tutorial-9i9i0r0o

Welcome to your in-depth tutorial on SPARQL (SPARQL Protocol and RDF Query Language), the standard query language for Linked Data. This guide will take you from the very basics to sophisticated querying techniques, using practical examples centered around CELLAR, the common metadata repository and knowledge graph of the Publications Office of the European Union. CELLAR underpins vital EU resources like EUR-Lex, offering a rich dataset of EU law, publications, and related information. My knowledge cutoff is Tuesday, 2025-05-06.

Key Insights: Your SPARQL Launchpad

  • SPARQL is SQL for Graphs: Understand how SPARQL queries RDF (Resource Description Framework) data, which is structured as interconnected subject-predicate-object triples, forming a graph.
  • CELLAR is Your Playground: Learn to navigate the EU's extensive legal and publication metadata stored in CELLAR, using its specific ontology (the Common Data Model - CDM).
  • From Simple to Sophisticated: Progress systematically from basic SELECT queries to advanced features like OPTIONAL patterns, UNION clauses, aggregations, CONSTRUCT queries, and inference.

Understanding the Foundations: SPARQL and RDF in CELLAR

Before diving into writing queries, it's crucial to grasp what SPARQL and RDF are, and how they relate to CELLAR.

What is RDF? The Language of Linked Data

Resource Description Framework (RDF) is a W3C standard for describing resources on the web. Data in RDF is represented as a collection of **triples**. Each triple consists of a:

  • Subject: The entity being described (e.g., a specific EU regulation).
  • Predicate: A property or relationship of the subject (e.g., "has title" or "was published on date").
  • Object: The value of the property or another entity related to the subject (e.g., "Regulation (EU) 2024/123" or "2024-03-15").

These triples link together to form a "knowledge graph," a web of interconnected data. CELLAR is such a knowledge graph, containing metadata about EU legal acts, publications, and more.

What is SPARQL? Querying the Graph

SPARQL is the query language specifically designed for RDF data. Think of it as the SQL equivalent for graph databases. Instead of querying tables and rows, SPARQL queries for patterns of triples within the RDF graph. It allows you to retrieve, manipulate, and explore the interconnected data stored in systems like CELLAR.

CELLAR: The EU's Knowledge Hub

CELLAR is the Publications Office of the European Union's common repository for metadata and content. It serves as the backbone for platforms like EUR-Lex. By providing a machine-readable SPARQL endpoint, CELLAR allows users and applications to directly query its vast collection of EU law and policy information. The official SPARQL endpoint for CELLAR is: https://publications.europa.eu/webapi/rdf/sparql.

To effectively query CELLAR, understanding its ontology, primarily the Common Data Model (CDM), is essential. Prefixes are used in SPARQL queries to shorten long URIs (Uniform Resource Identifiers) that define these ontologies.

Common prefixes for CELLAR include:

  • cdm: <http://publications.europa.eu/ontology/cdm#> (CELLAR Data Model)
  • eli: <http://data.europa.eu/eli/ontology#> (European Legislation Identifier)
  • dcterms: <http://purl.org/dc/terms/> (Dublin Core Terms, for metadata like title, date)
  • skos: <http://www.w3.org/2004/02/skos/core#> (Simple Knowledge Organization System, for concepts and labels)
  • xsd: <http://www.w3.org/2001/XMLSchema#> (XML Schema Datatypes, for literal types like dates and numbers)
Abstract image of a data center server room

CELLAR, like other large data repositories, relies on significant data center infrastructure.


The Anatomy of a SPARQL Query

A typical SPARQL query has several clauses that define what you're looking for and how the results should be presented.

Core Query Clauses

  • PREFIX: Defines abbreviations (prefixes) for long URIs, making queries more readable.
  • SELECT: Specifies the variables (data points) you want to retrieve in your results. Variables in SPARQL usually start with a ? or $.
  • WHERE: Contains the graph pattern to match against the data. This is where you define the triple patterns (subject, predicate, object) you are searching for.
  • FROM / FROM NAMED: Specifies the dataset(s) to query. For CELLAR, you typically query its public endpoint, but sometimes you might target specific named graphs within it.

Solution Modifiers

  • ORDER BY: Sorts the results based on one or more variables.
  • LIMIT: Restricts the number of results returned. Crucial for testing and managing large datasets.
  • OFFSET: Skips a specified number of results, useful for pagination.

This mindmap illustrates the key components involved in constructing a SPARQL query:

mindmap root["SPARQL Query Structure"] id1["Clauses"] id1_1["PREFIX"] id1_2["SELECT / CONSTRUCT / ASK / DESCRIBE"] id1_3["FROM / FROM NAMED"] id1_4["WHERE"] id1_4_1["Triple Patterns
(Subject Predicate Object)"] id1_4_2["FILTER"] id1_4_3["OPTIONAL"] id1_4_4["UNION"] id1_4_5["GRAPH"] id2["Modifiers"] id2_1["ORDER BY"] id2_2["LIMIT"] id2_3["OFFSET"] id2_4["GROUP BY"] id2_5["HAVING"] id3["Variables
(e.g., ?title, ?date)"] id4["Data Types & Literals
(e.g., xsd:date, strings, numbers)"] id5["Functions
(e.g., COUNT(), YEAR(), CONTAINS())"]

Basic SPARQL Queries with CELLAR Examples

Example 1: Retrieving Titles of Legal Documents

Let's start with a simple query to find the titles of some legal "Works" (a common entity type in CELLAR) and their URIs.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>

SELECT ?work ?title
WHERE {
  ?work a cdm:Work .         # ?work is of type cdm:Work
  ?work dcterms:title ?title . # ?work has a dcterms:title, which is ?title
}
LIMIT 10
  

Explanation:

  • PREFIX cdm: ... and PREFIX dcterms: ... define shorthand for common CELLAR and Dublin Core namespaces.
  • SELECT ?work ?title: We want to retrieve the URI of the work (?work) and its title (?title).
  • WHERE { ... }: This block contains the triple patterns.
  • ?work a cdm:Work .: This matches any subject (bound to ?work) that is an instance of (a is shorthand for rdf:type) cdm:Work.
  • ?work dcterms:title ?title .: This matches triples where the subject is the same ?work, the predicate is dcterms:title, and the object is bound to ?title.
  • LIMIT 10: Restricts the output to the first 10 results found.

Example 2: Filtering Results by Date

Now, let's find legal documents published after a specific date and order them.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?work ?title ?date
WHERE {
  ?work a cdm:Work ;
        dcterms:title ?title ;
        cdm:date_document ?date .  # In CELLAR, cdm:date_document is often used
  FILTER (?date > "2023-01-01"^^xsd:date)
}
ORDER BY DESC(?date)
LIMIT 5
  

Explanation:

  • PREFIX xsd: ... is added for XML Schema Datatypes, necessary for specifying xsd:date.
  • The semicolon ; is a shorthand. After the first triple pattern (?work a cdm:Work), it means the next triple pattern (dcterms:title ?title) shares the same subject (?work).
  • cdm:date_document ?date: Matches the document date. Note: Predicate names for dates can vary (e.g., dcterms:date, cdm:datePublished, cdm:work_date_document). Consulting CELLAR's documentation is key.
  • FILTER (?date > "2023-01-01"^^xsd:date): This clause restricts results to documents where the ?date is after January 1, 2023. The ^^xsd:date casts the string to an XSD date type for proper comparison.
  • ORDER BY DESC(?date): Sorts the results by date in descending order (most recent first).

This video provides an excellent introduction to writing your first SPARQL SELECT query, a fundamental skill for exploring CELLAR.

Example 3: Finding Regulations on a Specific Topic (String Matching)

Let's find regulations (a specific type of cdm:Work) whose titles contain the word "environment".


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>

SELECT ?regulation ?title ?subjectLabel
WHERE {
  ?regulation a cdm:Regulation ;        # ?regulation is of type cdm:Regulation
              dcterms:title ?title .
  
  # Option 1: Filter by title (less precise, but good for exploration)
  # FILTER(CONTAINS(LCASE(?title), "environment"))

  # Option 2: Filter by subject matter (more precise if using controlled vocabularies)
  ?regulation cdm:subjectMatter ?subjectConcept .
  ?subjectConcept skos:prefLabel ?subjectLabel .
  FILTER(CONTAINS(LCASE(?subjectLabel), "environment"))
}
LIMIT 10
  

Explanation:

  • ?regulation a cdm:Regulation: Narrows down to entities specifically typed as cdm:Regulation.
  • The query shows two approaches to finding "environment" related documents:
    • Filtering directly on the ?title using CONTAINS(LCASE(?title), "environment"). LCASE converts the title to lowercase for case-insensitive matching.
    • A more structured approach involves linking the regulation to its cdm:subjectMatter (which is usually a concept URI) and then getting the human-readable label (skos:prefLabel) for that concept. This is generally more reliable if the data is well-annotated with controlled vocabularies like EuroVoc.

Intermediate SPARQL: Optional Data, Unions, and Aggregations

Example 4: Retrieving Optional Information with OPTIONAL

Sometimes, a piece of information might not exist for all resources. OPTIONAL allows you to retrieve it if present, without excluding the resource if it's missing.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>

SELECT ?work ?title ?publicationDate ?entryIntoForceDate
WHERE {
  ?work a cdm:Work ;
        dcterms:title ?title ;
        cdm:date_document ?publicationDate . # Assuming this is the main publication date
  
  OPTIONAL {
    ?work cdm:date_entry_into_force ?entryIntoForceDate . # This date may not exist for all works
  }
}
LIMIT 10
  

Explanation:

  • The query retrieves works, their titles, and publication dates.
  • OPTIONAL { ?work cdm:date_entry_into_force ?entryIntoForceDate . }: It attempts to find the cdm:date_entry_into_force. If a work has this property, ?entryIntoForceDate will be bound. If not, the work is still included in the results, but ?entryIntoForceDate will be unbound (empty) for that specific result row.

Example 5: Combining Results with UNION

The UNION clause combines results from two or more graph patterns. For example, finding both Regulations and Directives published in a specific year.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?document ?title ?type
WHERE {
  {
    ?document a cdm:Regulation ;
              dcterms:title ?title ;
              cdm:date_document ?date .
    BIND("Regulation" AS ?type)
    FILTER(YEAR(?date) = 2023)
  }
  UNION
  {
    ?document a cdm:Directive ;
              dcterms:title ?title ;
              cdm:date_document ?date .
    BIND("Directive" AS ?type)
    FILTER(YEAR(?date) = 2023)
  }
}
LIMIT 10
  

Explanation:

  • The first block looks for cdm:Regulation documents from 2023.
  • The second block looks for cdm:Directive documents from 2023.
  • UNION combines the results from both blocks.
  • BIND("Regulation" AS ?type) creates a new variable ?type and assigns it a string value to help distinguish the document type in the results.
  • YEAR(?date) is a function that extracts the year from an xsd:date or xsd:dateTime literal.

Example 6: Aggregating Data with GROUP BY and COUNT

SPARQL supports aggregate functions like COUNT, SUM, AVG, MIN, MAX, often used with GROUP BY.

Let's count the number of regulations published per year.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT (YEAR(?date) AS ?year) (COUNT(?regulation) AS ?regulationCount)
WHERE {
  ?regulation a cdm:Regulation ;
              cdm:date_document ?date .
  FILTER(BOUND(?date)) # Ensure date exists for YEAR() function
}
GROUP BY YEAR(?date)
ORDER BY DESC(?year)
LIMIT 10
  

Explanation:

  • (YEAR(?date) AS ?year): Extracts the year from ?date and assigns it to a new variable ?year.
  • (COUNT(?regulation) AS ?regulationCount): Counts the number of regulations found for each group and assigns it to ?regulationCount.
  • FILTER(BOUND(?date)): Ensures that we only process entries where ?date has a value, as YEAR() might error on unbound values.
  • GROUP BY YEAR(?date): Groups the results by the extracted year. The aggregate function COUNT then operates on each group.
  • ORDER BY DESC(?year): Sorts the yearly counts, showing the most recent years first.

The following table summarizes common SPARQL clauses and their utility when querying CELLAR:

Clause Description Simplified CELLAR Example Snippet
PREFIX Defines a shorthand for a URI namespace. PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
SELECT Specifies the variables to be returned in the results. SELECT ?work ?title
WHERE Contains the graph patterns to match against the data. WHERE { ?work a cdm:Work . }
FILTER Restricts results based on a condition. FILTER (LANG(?title) = "en")
OPTIONAL Allows parts of the query to match if data exists, but doesn't fail if it's absent. OPTIONAL { ?work cdm:summary ?summary . }
UNION Combines results from multiple graph patterns. { ?doc a cdm:Regulation } UNION { ?doc a cdm:Directive }
ORDER BY Sorts the results. ORDER BY ?date_document
LIMIT Restricts the number of results returned. LIMIT 20
OFFSET Skips a specified number of results (for pagination). OFFSET 10
GROUP BY Groups rows that have the same values into summary rows. Used with aggregate functions. GROUP BY ?type (COUNT(?doc) AS ?count)
CONSTRUCT Returns an RDF graph constructed from the query results, rather than a table. CONSTRUCT { ?work cdm:title ?title . } WHERE { ... }

Advanced SPARQL: CONSTRUCT, Property Paths, Named Graphs, and Inference

Example 7: Creating RDF with CONSTRUCT

While SELECT returns tabular data, CONSTRUCT returns a new RDF graph based on the matched patterns. This is useful for transforming or exporting subsets of data.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX mydata: <http://example.org/mydata#> # Custom prefix

CONSTRUCT {
  ?work mydata:europeanTitle ?title .
  ?work mydata:publishedOn ?date .
}
WHERE {
  ?work a cdm:Regulation ;
        dcterms:title ?title ;
        cdm:date_document ?date .
  FILTER(LANG(?title) = "en" && YEAR(?date) = 2023)
}
LIMIT 5
  

Explanation:

  • CONSTRUCT { ... }: Defines the template for the RDF triples to be created. Here, it creates new triples using a custom mydata: predicate.
  • The WHERE clause selects English-titled regulations from 2023.
  • The output will be an RDF graph (e.g., in Turtle or RDF/XML format), not a table.

Example 8: Navigating Relationships with Property Paths

Property paths provide a concise way to specify traversals over one or more predicate links in the graph.

For example, to find a document and another document it amends (eli:amends), and potentially documents that amend the amendment (a chain).


PREFIX eli: <http://data.europa.eu/eli/ontology#>
PREFIX dcterms: <http://purl.org/dc/terms/>

SELECT ?originalDoc ?amendingDoc ?titleOriginal ?titleAmending
WHERE {
  ?amendingDoc eli:amends+ ?originalDoc . # '+' means one or more occurrences of eli:amends
  ?originalDoc dcterms:title ?titleOriginal .
  ?amendingDoc dcterms:title ?titleAmending .
  FILTER(LANG(?titleOriginal) = "en" && LANG(?titleAmending) = "en")
}
LIMIT 5
  

Explanation:

  • eli:amends+: This property path means "one or more sequential eli:amends relationships."
    • predicate*: Zero or more occurrences.
    • predicate?: Zero or one occurrence.
    • predicate1 / predicate2: A sequence of predicate1 followed by predicate2.
    • predicate1 | predicate2: Either predicate1 or predicate2.

Example 9: Querying Specific Named Graphs with GRAPH

RDF data can be organized into "named graphs." CELLAR might use named graphs to partition data (e.g., by year, dataset type). You can query a specific named graph.


PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>

# This is a hypothetical graph URI; actual CELLAR graph URIs need to be discovered
# FROM NAMED <http://publications.europa.eu/resource/graph/eurlex/directory_codes>

SELECT ?concept ?label
WHERE {
  GRAPH <http://publications.europa.eu/resource/graph/eurlex/directory_codes> { # Replace with an actual CELLAR named graph URI
    ?concept a skos:Concept ;
             skos:prefLabel ?label .
    FILTER(LANG(?label) = "en")
  }
}
LIMIT 10
  

Explanation:

  • GRAPH <graph-uri> { ... }: The triple patterns inside the curly braces will only be matched against the data within the specified named graph.
  • Discovering relevant named graph URIs in CELLAR requires exploring its documentation or querying for available graphs.

Example 10: Using Inference in CELLAR

Some SPARQL endpoints can perform inference, deriving new triples based on ontologies and rules. CELLAR supports this. For instance, if A is a subclass of B, and X is an instance of A, inference can deduce X is also an instance of B.


DEFINE input:inference "cdm_rule_set" # Instruction to activate CELLAR's inference rules

PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
PREFIX dcterms: <http://purl.org/dc/terms/>

SELECT ?document ?title
WHERE {
  # This query might return more results with inference enabled
  # if cdm:LegalDocument is a superclass of more specific types like cdm:Regulation
  ?document a cdm:LegalDocument ; 
            dcterms:title ?title .
  FILTER(LANG(?title) = "en")
}
LIMIT 10
  

Explanation:

  • DEFINE input:inference "cdm_rule_set": This non-standard (but used by CELLAR's Virtuoso backend) directive enables a predefined set of inference rules. The specific rule set name (cdm_rule_set) is specific to CELLAR.
  • With inference, queries can return results that are logically implied but not explicitly stated in the raw data.

The capabilities of different SPARQL query forms can be visualized. While SELECT is for data retrieval, CONSTRUCT is for graph generation, ASK for boolean checks, and DESCRIBE for resource descriptions. This radar chart offers a conceptual comparison:


Tools and Best Practices for Querying CELLAR

  • CELLAR SPARQL Endpoint: The primary interface for submitting queries is https://publications.europa.eu/webapi/rdf/sparql. Many SPARQL clients can connect to this URL.
  • Flint SPARQL Editor: The EU Law and Publications Portal often provides access to tools like Flint, offering a user interface for writing and executing queries against CELLAR.
  • Programming Libraries:
    • R: The eurlex package simplifies interaction with EU data sources, including constructing and running SPARQL queries on CELLAR.
    • Python: Libraries like pyeurlex or general-purpose RDF libraries (e.g., rdflib with SPARQLWrapper) allow programmatic access to CELLAR.
  • Understand the CELLAR Ontology (CDM): Familiarize yourself with the Common Data Model. The Publications Office provides documentation on the structure, classes (e.g., cdm:Work, cdm:Regulation), and properties (e.g., dcterms:title, cdm:date_document) used in CELLAR. This is crucial for writing effective queries.
  • Start Simple and Iterate: Begin with basic queries and gradually add complexity. Use LIMIT extensively during development to get quick feedback.
  • Check Predicate Names: Property names can be specific. For example, while dcterms:date is standard, CELLAR often uses cdm:date_document or cdm:work_date_document for the main date of a document.

Frequently Asked Questions (FAQ)

What is the difference between SPARQL and SQL?

SQL (Structured Query Language) is designed for relational databases, which store data in tables with rows and columns. SPARQL is designed for RDF (Resource Description Framework) data, which is stored as a graph of interconnected triples (subject-predicate-object). While both are query languages, they operate on fundamentally different data models. SPARQL excels at navigating relationships and querying heterogeneous, linked data.

How do I find the correct predicates (properties) to use for CELLAR data?

The best way is to consult the official documentation for CELLAR and its Common Data Model (CDM) provided by the EU Publications Office. You can also explore existing data by querying for all predicates associated with a known resource URI (e.g., SELECT DISTINCT ?p WHERE { <known_uri> ?p ?o . }) or by using a SPARQL endpoint's browsing interface if available.

Why are my SPARQL queries slow or timing out?

Large, complex RDF datasets like CELLAR can lead to slow queries if they are not optimized. Common reasons include:

  • Very broad patterns that match too many triples initially.
  • Complex FILTER conditions applied late in the query.
  • Extensive use of OPTIONAL patterns without sufficient constraints.
  • Not using LIMIT during testing.
Try to make your patterns as specific as possible early in the WHERE clause. Use FILTERs strategically. Break down complex queries into smaller parts if feasible.

What are common resource types in CELLAR?

CELLAR's Common Data Model (CDM) defines various resource types. Some frequently encountered ones include:

  • cdm:Work: The abstract concept of a publication or legal act (e.g., a specific regulation).
  • cdm:Expression: A specific version or language of a Work (e.g., the English PDF version of a regulation).
  • cdm:Manifestation: A concrete embodiment of an Expression (e.g., a particular file format like PDF or HTML).
  • cdm:Regulation, cdm:Directive, cdm:Decision: Specific types of legal acts.
  • cdm:LegalResource: A broader category for legal documents.
Understanding these distinctions helps in formulating precise queries.


Recommended Further Exploration

To deepen your understanding of SPARQL and CELLAR, consider exploring these related queries:


References

gnome.pages.gitlab.gnome.org
Tsparql – 3.0: SPARQL Tutorial
docs.data.world
SPARQL Tutorial

Last updated May 6, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask Ithy AI