D2RQ V0.3 - Treating Non-RDF Relational Databases as Virtual RDF Graphs

User Manual and Language Specification

This Version:
http://www.wiwiss.fu-berlin.de/suhl/bizer/d2rq/spec/20040804/
Latest Version:
http://www.wiwiss.fu-berlin.de/suhl/bizer/d2rq/spec/
Authors:
Chris Bizer (Freie Universität Berlin, Germany)
Richard Cyganiak (Freie Universität Berlin, Germany)
Jörg Garbers (Freie Universität Berlin, Germany) V0.2 to V0.3 code.

 


Abstract

As Semantic Web technologies are getting mature, there is a growing need for RDF applications to access the content of huge, live, non-RDF, legacy databases without having to replicate the whole database into RDF. This document describes D2RQ V0.3, a declarative mapping language for treating non-RDF relational databases as virtual RDF graphs within the Jena Semantic Web development toolkit.

Table of Contents


1. Introduction

This document describes D2RQ V0.3, a declarative mapping language for treating non-RDF, relational databases as virtual, read-only RDF graphs within the Jena toolkit [Jena]. D2RQ offers a flexible access mechanism to the content of huge, non-RDF databases without having to replicate the database into RDF. Thus, it allows the integration of legazy databases into the data access architecture currently standardized by the W3C Data Access Working Group [DAWG].

Using D2RQ you can:

D2RQ is implemented as a Jena graph, the basic information representation object within the Jena framework. A D2RQ graph wraps one or more local relational databases into a virtual, read-only RDF graph. It rewrites Jena API calls, find() and RDQL queries to application-data-model specific SQL queries. The result sets of these SQL queries are transformed into RDF triples which are passed up to the higher layers of the Jena framework.

For using D2RQ within your applications, you just have to include the d2rq.jar file into your class path and write a D2RQ mapping between the ontology used by your application and your local database.

 


2. Architecture

D2RQ consists of:

D2RQ Example

We are using an example database which stores information about conferences, papers, authors and topics through this manual. The database is mapped to the International Semantic Web Community (ISWC) Ontology.

The examples below show:

 


3. Language Specification

D2RQ is a declarative mapping language for describing the relation between relational database schemata and OWL/RDFS ontologies. A D2RQ map is an RDF document.

The language is formally defined by the D2RQ RDF-S Schema.
The D2RQ namespace is http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#

An ontology is mapped to a database schema using d2rq:ClassMaps, d2rq:DatatypePropertyBridges and d2rq:ObjectPropertyBridges. The central object within D2RQ and also the object to start with when writing a new D2RQ map is the ClassMap. A ClassMap represents a class or a group of similar classes of the ontology. A ClassMap specifies how instances of the class are identified. It has a set of PropertyBridges, which specify how the properties of an instance are created. D2RQ maps have the following general structure:

 

The D2RQ map below relates the table conferences in a database to the class conference in an ontology. You can use it as a template for writing your own maps.

# D2RQ Namespace  
@prefix d2rq:        <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#> .

# Namespace of the ontology
@prefix : <http://annotation.semanticweb.org/iswc/iswc.daml#> .

# Namespace of the database
@prefix db1: <http://www.example.org/dbserver01/db01#> .

# Other namespaces
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 

# -----------------------------------------------
# Database

db1:Database1 rdf:type d2rq:Database;
              d2rq:odbcDSN "IswcDB";
              d2rq:numericColumn "Conferences.ConfID";
              d2rq:textColumn "Conferences.Name";
              d2rq:textColumn "Conferences.Location" .

# -----------------------------------------------
# Conference table / class
#
# CREATE TABLE Conferences (
# ConfID int(11) default NULL,
# Name text,
# Location text
#) TYPE=MyISAM;

db1:Conference rdf:type d2rq:ClassMap ;
            d2rq:class :Conference ;
            d2rq:uriPattern "http://conferences.org/comp/confno@@Conferences.ConfID@@" ;
            d2rq:dataStorage db1:Database1 .

db1:eventTitle rdf:type d2rq:DatatypePropertyBridge ;
            d2rq:property :eventTitle ;
            d2rq:column "Conferences.Name" ;
            d2rq:belongsToClassMap db1:Conference ;
            d2rq:datatype xsd:string .

db1:location rdf:type d2rq:DatatypePropertyBridge ;
            d2rq:property :location ;
            d2rq:column "Conferences.Location" ; 
            d2rq:belongsToClassMap db1:Conference ;
            d2rq:datatype xsd:string . 

The D2RQ language constructs are described in detail below:

 

3.1 Database

A d2rq:Database defines an ODBC or JDBC connection to a local relational database and specifies the type of the database columns used by D2RQ. A D2RQ map can contain several d2rq:Databases for accessing different local databases.

Properties

d2rq:odbcDSN The ODBC data source name of the database.
d2rq:jdbcDriver The JDBC driver for the database. Used together with d2rq:jdbcDSN.
d2rq:jdbcDSN The JDBC data source name of the database.
d2rq:username A username if required by the database.
d2rq:password A password if required by the database.
d2rq:textColumn Specifies that a database column contains text values. D2RQ will use ' quotes around values from this column in SQL statements.
d2rq:numericColumn Specifies that a database column contains numeric values. D2RQ will not quote values from this column in SQL statements.
d2rq:dateColumn Specifies that a database column contains dates. D2RQ will use # quotes around values from this column in SQL statements.
d2rq:allowDistinct Specifies the databases ability to handle DISTINCT correctly. Value: "true" or "false". For example MSAccess cuts fields longer than 256 chars.
d2rq:expressionTranslator Specifies a Java class that can translate Jena RDQL expression objects into SQL expressions that are understood by the database. "null" means: no expression translation. Otherwise full SQL 92 is assumed. For Example MySQL is not completely SQL 92 conform (string concatenation ...).

d2rq:numericColumn, d2rq:textColumn, d2rq:dateColumn define the quoting style used within SQL WHERE clauses. You must define the column type for all columns that are used in d2rq:column, d2rq:pattern, d2rq:uriColumn, d2rq:uriPattern and d2rq:bNodeIdColumns statements. You don't have to define the type for columns that are only used in d2rq:join or d2rq:condition statements.

Example

db1:Database1 rdf:type d2rq:Database;
              d2rq:odbcDSN "IswcDB";
              d2rq:username="joseki";
              d2rq:password="*****";
              d2rq:numericColumn "Conferences.ConfID";
              d2rq:textColumn "Conferences.URI";
              d2rq:textColumn "Conferences.Name";
              d2rq:textColumn "Conferences.Location";
              d2rq:dateColumn "Conferences.Date".

A note on using multiple databases within a single D2RQ map: You cannot link from one database by having a property bridge with d2rq:belongsToClassMap in one database and d2rq:refersToClassMap in the other. Instead, define class maps in both databases that create the same URIs or blank node IDs.

 

3.2 ClassMap

A d2rq:ClassMap represents a class or a group of similar classes of an OWL ontology or RDFS schema. A class map defines how instances of the class are identified. Instances can be identified using URIrefs or blank nodes. URIrefs can be created with d2rq:uriColumn and d2rq:uriPattern. Blank nodes are created with d2rq:bNodeIdColumns. A ClassMap has a set of d2rq:PropertyBridges and is connected to a d2rq:Database which represents the database where instance data is stored.

Properties

d2rq:class An RDF-S or OWL class. All resources generated by this ClassMap are instances of this class.
d2rq:uriPattern

Pattern used for URIref construction and reversing. A Pattern is a string containing database column names separated by the rest of the pattern by @@ deliminators. Column names are replaced by values from the database in the mapping process. A uriPattern has to contain the primary key column or columns for identifying a class instance. Database column names have to be given in the form "TableName.ColumnName". If a pattern contains more than one column, then a separating string, which must not occur in the column values, has to be used to separate the column names, in order to allow D2RQ reversing given URIrefs into column values.

Example pattern:
"http://example.org/lineItems/item@@Orders.orderID@@-@@LineItems.itemID@@"

d2rq:uriColumn Database column containing URIrefs for identifying instances. The database column name have to be given in the form "TableName.ColumnName".
d2rq:bNodeIdColumns bNodeIdColumns is used if instances are identified using bNodes. The bNodeIdColumns property specifies a column name or a list of columns separated by commas, which contain the primary key information for identifying instances. The primary key values are used together with the ClassMap name to generate bNode labels. Database column names have to be given in the form "TableName.ColumnName".
d2rq:translateWith Assigns a d2rq:TranslationTable to the class map. Values from the d2rq:uriColumn or d2rq:uriPattern will be translated by the table before a resource is generated. See section 3.5 for details.
d2rq:dataStorage Reference to a d2rq:Database where the instance data is stored.
d2rq:containsDuplicates Must be specified if a class map uses information from tables that are not fully normalized. If the d2rq:containsDuplicates property value is set to "true", then D2RQ adds a DISTINCT clause to all queries using this classMap. "False" is the default value, which doesn't have to be explicitly declared. Adding this property to class maps based on normalized database tables degrades query performance, but doesn't affect query results.
d2rq:additionalProperty Adds an AdditionalProperty to all instances of this class. This might be useful for adding rdf:seeAlso properties or other fixed statements to all instances of the class.
d2rq:condition Specifies an SQL WHERE condition. An instance of this class will only be generated for database rows that satisfy the condition. Conditions can be used to hide parts of the database from D2RQ, e.g. deny access to data which is older or newer than a certain date. See section Conditional Mappings for details.

ClassMap property:

d2rq:classMap Inverse of d2rq:class and unnecessary if d2rq:class is used. Specifies that a d2rq:classMap is used to create instances of an OWL or RDF-S class.

 

Example: ClassMap where instances are identified using an URI pattern

:InProceedings rdf:type rdfs:Class ;
     rdfs:comment "The class Inproceedings (Papers) in the RDF-S schema." .

db1:InProceedingsClassMap rdf:type d2rq:ClassMap ;
    d2rq:uriPattern "http://www.conference.org/conf02004/paper#Paper@@Papers.PaperID@@" ;
    d2rq:class :InProceedings ;
    d2rq:dataStorage db1:Database1 .

The d2rq:class property is used to state that all resources generated by the d2rq:ClassMap are instances of an RDFS or OWL class. D2RQ automatically creates the necessary rdf:type triples.

 

Example: ClassMap where instances are identified using blank nodes

db1:Topic rdf:type d2rq:ClassMap ;
    d2rq:bNodeIdColumns "Topics.TopicID" ;
    d2rq:class :Topic ;
    d2rq:dataStorage db1:Database1 .

In order to recognize bNodes across several find() calls and to be able to map bNodes to instance data in the database, D2RQ encodes the classMap name together with the primary key values in the bNode label. The map above could produce the bNode label "http://www.example.org/dbserver01/db01#Topic@@6", where the number "6" is a primary key value and "http://www.example.org/dbserver01/db01#Topic" is the ClassMap name.

 

Example: ClassMap for a group of classes with the same properties

If you want to use one ClassMap for a group of classes with the same properties (like Person, Professor, Researcher, Student) that all come from the same table, you must create the rdf:type statements with an object property bridge instead of using d2rq:class.

db1:PersonsClassMap rdf:type d2rq:ClassMap ;
       d2rq:uriColumn "Persons.URI" ;
       d2rq:dataStorage db1:Database1 .

db1:PersonsType rdf:type d2rq:ObjectPropertyBridge ;
      d2rq:property rdf:type ;
      d2rq:pattern "http://annotation.semanticweb.org/iswc/iswc.daml#@@Persons.Type@@" ; 
      d2rq:belongsToClassMap db1:PersonsClassMap .

Here, the class of each person is obtained by prefixing the values of the Persons.Type column with an ontology namespace. If the class names within the ontology can't be constructed directly from values of the Persons.Type column, then a TranslationTable could be used for aligning class names and database values.

 

3.3 Property Bridges

Property Bridges relate database table columns to RDF properties. They are used to construct URIs, blank nodes and literals from database values and to reverse given RDF constructs back to database values. There are two types of property bridges:

Common properties

d2rq:belongsToClassMap Specifies that the property bridge belongs to a d2rq:ClassMap. Must be specified for every property bridge.
d2rq:property The RDF property that connects the ClassMap with the object or literal created by the bridge. Must be specified for every property bridge.
d2rq:join If the columns used to create the literal value or object are not from the database table(s) that contains the ClassMap's columns, then the tables have to be joined together using one or more d2rq:join properties. See example below.
d2rq:alias Aliases are used to join a table with itself. This can be used to express a "works for" or "is child of" property.
d2rq:condition Specifies an SQL WHERE condition. The bridge will only generate a statement if the condition holds. A common usage is to suppress triples with empty literal values: d2rq:condition "Table.Column <> ''". See section Conditional Mappings for details.
d2rq:translateWith Assigns a d2rq:TranslationTable to the property bridge. Values from the d2rq:column or d2rq:pattern will be translated by the table. See section TranslationTables for details.
d2rq:valueMaxLength Asserts that all values of this bridge are not longer than a number of characters. This allows D2RQ to speed up queries. See section Performance Optimization for details.
d2rq:valueContains Asserts that all values of this bridge always contain a given string. This allows D2RQ to speed up queries. Most useful in conjunction with d2rq:column. See section Performance Optimization for details.
d2rq:valueRegex Asserts that all values of this bridge match a given regular expression. This allows D2RQ to speed up queries. Most useful in conjunction with d2rq:column on columns whose values are very different from other columns in the database. See section Performance Optimization for details.

PropertyBridge property:

d2rq:propertyBridge Inverse of d2rq:property and not needed if d2rq:property is used. The d2rq:propertyBridge property specifies which property bridge is used for an RDF property. If the same RDF property is used by several RDF classes, then several property bridges are used to relate the RDF property to the different class maps.

 

Example

:title rdf:type rdf:Property .

db1:inProceedingsTitle rdf:type d2rq:DatatypePropertyBridge;
       d2rq:belongsToClassMap db1:InProceedings ;
       d2rq:property :title ;
       d2rq:column "Papers.Title" .

This generates RDF triples whose subjects come from the db1:InProceedings ClassMap, the predicate is :title, and the objects are taken from the Papers.Title column.

 

3.3.1 DatatypePropertyBridge

Datatype property bridges are used to construct literal property values from database values.

Properties

d2rq:column Database column that contains the literal value. Column names have to be given in the form "TableName.ColumnName".
d2rq:pattern Pattern to create the property value. Patterns can be used to extend column values before they are used as property values. Patterns can also be used to merge several column values to one property value. If a pattern contains more than one column, then a separating string, which cannot occur in the column values, has to be used between the column names, in order to allow D2RQ reversing given literals into column values.
d2rq:datatype Specifies the datatype of the literal.
d2rq:lang Specifies the language of the literal.

 

Example: Datatype property bridge using a column from the same table as the class map

:abstract   rdf:type rdf:Property .

db1:inProceedingsAbstract rdf:type d2rq:DatatypePropertyBridge ;
            d2rq:belongsToClassMap db1:InProceedings ;
            d2rq:property :abstract ;
            d2rq:column "Papers.Abstract" ; 
            d2rq:lang "en" .

The values of the column "Papers.Abstract" is used to create the property abstract. The language is set to English and the property bridge belongs to the class map db1:InProceedings.

Example: Datatype property bridge using information from different database tables

:authorName rdf:type rdf:Property .

db1:authorNameBridge rdf:type d2rq:DatatypePropertyBridge ;
            d2rq:belongsToClassMap db1:Papers ;
            d2rq:property :authorName ;
            d2rq:column "Persons.Name";
            d2rq:join "Papers.PaperID = Rel_Person_Paper.PaperID" ;
            d2rq:join "Rel_Person_Paper.PersonID = Persons.PerID" ;
            d2rq:datatype xsd:string .

This property bridge adds the names of authors to papers. If a paper has several authors, then several authorName properties are added. Because of the n:m relation between InProceedings and Persons, the d2rq:join clauses join the tables Papers and Persons over the table Rel_Person_Paper.

 

3.3.2 ObjectPropertyBridge

Object property bridges are used to construct URIs and to refer to instances of other class maps.

Properties

d2rq:column Database column that contains URIs. Column names have to be given in the form "TableName.ColumnName".
d2rq:pattern Pattern to create the property value. If a pattern that contains more than one column, then a separating string, which cannot occur in the column values, has to be used between the column names, in order to allow D2RQ reversing given URIs into column values.
d2rq:refersToClassMap Reference to a d2rq:ClassMap. d2rq:refersToClassMap has to be used together with d2rq:join when a property refers to instances created by other classMaps. D2RQ uses the uriPattern, uriColumn or bNodeIdColumn properties of the referred class map to construct the property value. See example below.

Example: Object property bridge using a column from the same table as the class map

:eMail rdf:type rdf:Property ,
            
db1:PersonsClassEmail rdf:type d2rq:ObjectPropertyBridge ;
            d2rq:belongsToClassMap db1:PersonsClassMap ;
            d2rq:property :email ;
            d2rq:pattern "mailto:@@Persons.Email@@" .

The pattern "mailto:@@Persons.Email@@" is used together with the values of the column "Persons.Email" to create email property values. The property bridge belongs to the class map db1:PersonsClassMap.

Example: Object property bridge using information from two database tables

:conference rdf:type rdf:Property .

db1:conferenceBridge rdf:type d2rq:ObjectPropertyBridge ;
            d2rq:belongsToClassMap db1:Papers ;
            d2rq:property :conference ;
            d2rq:refersToClassMap db1:Conference ;
            d2rq:join "Papers.Conference = Conferences.ConfID" .

There is a 1:n relation between conferences and papers, which is expressed by the d2rq:join property. The :conference property refers to instances of the class map db1:Conference. D2RQ uses the uriPattern of this class map to construct the property values.

 

3.4 AdditionalProperty

A d2rq:AdditionalProperty can be used to add a fixed statement to all instances generated by a class map. The statement is added to the result sets, if patterns like (ANY, ANY, ANY), (URI, ANY, ANY) or (URI, additionalPropertyName, ANY) are used. The d2rq:additionalProperty property is used to link from the class map to the d2rq:AdditionalProperty definition.

Properties

d2rq:propertyName The RDF property to be used as the predicate of all fixed statements.
d2rq:propertyValue The value to be used as the object of all fixed statements.

Example:

db1:PersonsClassMap rdf:type d2rq:ClassMap;
        d2rq:class :Person;
        d2rq:additionalProperty db1:SeeAlsoStatement.

db1:SeeAlsoStatement rdf:type d2rq:AdditionalProperty;
        d2rq:propertyName rdfs:seeAlso;
        d2rq:propertyValue <http://annotation.semanticweb.org/iswc2003/>.

This adds an rdfs:seeAlso statement with a fixed URL object to every instance of the class map.

 

3.5 Translation Tables

A d2rq:TranslationTable is an additional layer between the database and the RDF world. It translates back and forth between values taken from the database and RDF URIs or literals. A translation table can be attached to a class map or a property bridge using the d2rq:translateWith property. TranslationTables can be used only for mappings that are unique in both directions (1:1).

Properties

d2rq:translation Adds a d2rq:Translation to the table.
d2rq:href Links to a CSV file containing translations. Each line of the file is a translation and contains two strings separated by a comma. The first one is the DB value, the second the RDF value.
d2rq:javaClass The qualified name of a Java class that performs the mapping. The class must implement the Translator interface. Custom Translators might be useful for encoding and decoding values, but are limited to 1:1 translations. Further datails can be found in the D2RQ javadocs.

 

3.5.1 Translation

A d2rq:Translation is a single entry in a d2rq:TranslationTable.

Properties

d2rq:dbValue A value that might appear in a database column or might be generated by a d2rq:pattern.
d2rq:rdfValue A translation of that value to be used in RDF constructs.

Example: Translating color codes

A typical application are database columns containing type codes or similar enumerated values. A translation table can be used to turn them into RDF resources. In this example, the column ShinyObject.Color contains a color code: "R" for red, "G" for green etc. These codes must be translated into RDF resources: :red, :green etc.

:red rdf:type :Color;
:green rdf:type :Color;
# ... more colors omitted ...
:blue rdf:type :Color;

db1:ColorBridge rdf:type d2rq:ObjectPropertyBridge;
        d2rq:belongsToClassMap db1:ShinyObjectMap;
        d2rq:property :color;
        d2rq:column "ShinyObject.Color";
        d2rq:translateWith db1:ColorTable.

db1:ColorTable rdf:type d2rq:TranslationTable;
        d2rq:translation [ d2rq:dbValue "R"; d2rq:rdfValue :red; ];
        d2rq:translation [ d2rq:dbValue "G"; d2rq:rdfValue :green; ];
        # ... more translations omitted ...
        d2rq:translation [ d2rq:dbValue "B"; d2rq:rdfValue :blue; ].

The d2rq:translateWith statement tells D2RQ to look up database values in the db1:ColorTable. There, a translation must be given for each possible value. If the database contains values which are not in the translation table, D2RQ will not generate a :color statement for that :ShinyObject instance.

Note that the type of the resulting node is determined by the type of the bridge and not by the node type of the rdfValues. db1:ColorBridge is a d2rq:ObjectPropertyBridge. Thus, the translation will create resources. If it would be a d2rq:DatatypePropertyBridge then literals would be created.

 

3.6 Conditional Mappings

Sometimes only certain information from a database should be accessible, because parts of the database might be confidential or outdated. Using d2rq:condition you can specify conditions, which must be satisfied by all accessible data.

You can use d2rq:condition on class map and property bridge level. The d2rq:condition value is added as an additional SQL WHERE clause to all queries generated using the class map or property bridge. If the condition evaluates to FALSE for a SQL result set row, then no triples will be generated from that row.

Example: Using d2rq:condition on a d2rq:ClassMap

db1:InProceedings rdf:type d2rq:ClassMap;
            d2rq:class :InProceedings;
            d2rq:uriPattern "http://www.conference.org/conf02004/paper#Paper@@Papers.PaperID@@";
            d2rq:condition "Papers.Publish = 1";
            d2rq:dataStorage db1:Database1.

Only those papers with a value of 1 in the Papers.Publish column will be accessible. All other papers are ignored.

Example: Filtering zero-length strings

Usually, the special value NULL is used in a database to indicate that some field has no value, or that the value is unknown. Some databases, however, are using a zero-length string ("") instead. D2RQ doesn't generate RDF statements from NULL values, but it doesn't recognize zero-length strings and will generate statements like :Person123 :firstName "". if the person's first name is a zero-length string. In oder to suppress these statements, a d2rq:condition can be added to the property bridge:

db1:PersonsClassFirstName rdf:type d2rq:DatatypePropertyBridge;
            d2rq:property :firstName;
            d2rq:column "Persons.FirstName";
            d2rq:belongsToClassMap db1:PersonsClassMap;
            d2rq:condition "Persons.FirstName <> ''".

Example: Relationship type codes

Imagine a table Rel_Paper_Topic that associates rows from a Papers table with rows from a Topics table. The Rel_Paper_Topic table contains a PaperID column to reference the papers, a TopicID to reference the topics, and a RelationshipType column which contains 1 if the topic is a primary topic of the paper, and 2 if it is a secondary topic.

For primary topic relationships, the :primaryTopic property shall be used, and for others the :secondaryTopic property.

We can build a map for this scenario by creating two property bridges. One for :primaryTopic, one for :secondaryTopic. We add a d2rq:condition to both bridges to suppress those statements where the RelationshipType column doesn't have the correct value.

db1:primaryTopic rdf:type d2rq:ObjectPropertyBridge;
            d2rq:belongsToClassMap db1:InProceedings;
            d2rq:property :primaryTopic;
            d2rq:refersToClassMap db1:Topic;
            d2rq:join "Papers.PaperID = Rel_Paper_Topic.PaperID";
            d2rq:join "Rel_Paper_Topic.TopicID = Topics.TopicID";
            d2rq:condition "Rel_Paper_Topic.RelationType = 1".

db1:secondaryTopic rdf:type d2rq:ObjectPropertyBridge;
            d2rq:belongsToClassMap db1:InProceedings;
            d2rq:property :secondaryTopic;
            d2rq:refersToClassMap db1:Topic;
            d2rq:join "Papers.PaperID = Rel_Paper_Topic.PaperID";
            d2rq:join "Rel_Paper_Topic.TopicID = Topics.TopicID";
            d2rq:condition "Rel_Paper_Topic.RelationType = 2".

 

3.7 Performance Optimization using Hint Properties

This section covers hint properties that can be added to property bridges in order to speed up queries: d2rq:valueMaxLength, d2rq:valueRegex and d2rq:valueContains.

Example: Providing a maximum length

db1:PersonsClassFirstName rdf:type d2rq:DatatypePropertyBridge;
            d2rq:property :firstName;
            d2rq:column "Persons.FirstName";
            d2rq:belongsToClassMap db1:PersonsClassMap;
            d2rq:valueMaxLength "15".

The d2rq:valueMaxLength property can be used to tell D2RQ that the length of Persons.FirstName values is limited to 15 characters. Using this information, D2RQ doesn't have to look in the database anymore to figure out, that a given FirstName which is longer than 15 characters isn't fitting.

Example: Providing a regular expression

db1:inProceedingsYear rdf:type d2rq:DatatypePropertyBridge;
            d2rq:property :year;
            d2rq:column "Papers.Year";
            d2rq:belongsToClassMap db1:InProceedings;
            d2rq:datatype xsd:gYear;
            d2rq:valueRegex "^[0-9]{4}$".

Here, the d2rq:valueRegex property is used to provide a regular expression for the Papers.Year column. The statement asserts that all values match the regular expression (or are NULL). The expression ^[0-9]{4}$ matches every four-digit number. If you don't want to use the full regular expression machinery, you can use d2rq:valueContains to assert that all values generated by the property bridge contain a certain phrase.

You are geting the largest performance gain by providing hints for property bridges which are using d2rq:column. You should define hints on columns of large tables and on columns that are not indexed by the database. These are the cases where a well-placed optimization hint can result in an order-of-magnitude improvement for some queries. Don't bother to provide hints for property bridges based on d2rq:pattern. These can be optimized very well without hints. In general, the biggest payoff is expected for hints on large tables. If you have a few very large tables with non-indexed columns in your database, that's where you should focus your efforts.

Please keep in mind that hint properties are not intended for filtering of unwanted database values. They are only performance hints. Values that do not fulfill the criteria will still appear in query results if find patterns like (URI, ANY, ANY) are used. In oder to filter values, use d2rq:condition or a translation table with a custom Java class that returns null for unwanted database values.

 

3.8 Processing Instructions

To configure the D2RQ mapping by modifying the source code is one option. A better one for most of the users is to specify a configuration within the D2RQ map.

Example: Specifying a different query handler

:ProcessingInstructions1 rdf:type d2rq:ProcessingInstructions;
            d2rq:queryHandler "com.hp.hpl.jena.graph.query.SimpleQueryHandler".

The d2rq:queryHandler property can be used to specify a query handler that is different from the default query handler which in V0.3 is D2RQQueryHandler. So if You wonder wether the bug is in the new features of V0.3, switch back to the slow but highly tested SimpleQueryHandler.

 


4. Using D2RQ within Jena

This section describes how D2RQ is used within the Jena 2 Semantic Web framework.

Download

Jena 2 can be downloaded from http://jena.sourceforge.net/downloads.html
D2RQ can be downloaded from http://sourceforge.net/projects/d2rq-map/

Installation

You have to add the "d2rq.jar" file from the "bin" directory of the D2RQ distribution together with the Jena2 jar files to your classpath.

If you want to see how D2RQ translates Jena graph API calls into SQL statements, you can switch into debug mode by calling enableDebug on the D2RQ model or graph object.

 

4.1 Using D2RQ with the Jena model API

The following example shows how the Jena model API is used to check if the paper with the URI "http://www.conference.org/conf02004/paper#Paper1" has an iswc:author property.

import com.hp.hpl.jena.rdf.model.* ;
import de.fuberlin.wiwiss.d2rq.*;

...

String D2RQMap = "file:///C:/D2RQ/maps/ISWC-d2rq.n3";
ModelD2RQ d2rqModel = null;
// Create D2RQ Model try {
d2rqModel = new ModelD2RQ(D2RQMap);
} catch (D2RQException ex) {
System.out.println(ex.toString());
} // Get the ressource Paper 1 String paperURI = "http://www.conference.org/conf02004/paper#Paper1";
Resource paperRessource = d2rqModel.getResource(paperURI);
// Check if Paper 1 has an auhor property Property author = d2rqModel.createProperty("http://annotation.semanticweb.org/iswc/iswc.daml#author");
if (paperRessource.hasProperty(author))      System.out.println("The paper has an author.");

 

4.2 Using find(spo) and D2RQ

The following example shows how the Jena graph API is used to get all papers which have been published in 2003.

import com.hp.hpl.jena.graph.* ;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.datatypes.*; import de.fuberlin.wiwiss.d2rq.*; ... String D2RQMap = "file:///C:/D2RQ/maps/ISWC-d2rq.n3";
GraphD2RQ d2rqGraph = null;
// Create D2RQ Graph try {
d2rqGraph = new GraphD2RQ(D2RQMap);
} catch (D2RQException ex) {
System.out.println(ex.toString());
} // Create a find(spo) pattern Node subject = Node.ANY;
Node predicate = Node.createURI("http://annotation.semanticweb.org/iswc/iswc.daml#year");
RDFDatatype dtYear = TypeMapper.getInstance().getSafeTypeByName("http://www.w3.org/2001/XMLSchema#gYear");
Node object = Node.createLiteral("2003", null, dtYear);
Triple pattern = new Triple(subject, predicate, object);
// Query the graph ExtendedIterator resultiterator = d2rqGraph.find(pattern);
// Output the query results while (resultiterator.hasNext()) {
System.out.println("Result Triple :" + ((Triple) resultiterator.next()).toString());
}

 

4.3 Using RDQL and D2RQ

The following example shows how RDQL is used to get all information about the paper with the URI "http://www.conference.org/conf02004/paper#Paper1". The results are displayed using a QueryResultsFormatter.

import com.hp.hpl.jena.rdf.model.* ;
import com.hp.hpl.jena.rdql.*;
import java.io.PrintWriter;
import de.fuberlin.wiwiss.d2rq.*;

...

String D2RQMap = "file:///C:/D2RQ/maps/ISWC-d2rq.n3";
ModelD2RQ d2rqModel = null;
// Create D2RQ Model try {
d2rqModel = new ModelD2RQ(D2RQMap);
} catch (D2RQException ex) {
System.out.println(ex.toString());
} // Query the model String rdql = "SELECT ?x, ?y WHERE (<http://www.conference.org/conf02004/paper#Paper1>, ?x, ?y)";
Query query = new Query(rdql);
query.setSource(d2rqModel);
QueryExecution qe = new QueryEngine(query) ;
QueryResults results = qe.exec() ;
// Output the query results using a QueryResultsFormatter QueryResultsFormatter fmt = new QueryResultsFormatter(results) ;
PrintWriter pw = new PrintWriter(System.out) ;
fmt.printAll(pw, " | ") ;
pw.flush() ;
fmt.close() ;
results.close() ;

 

 


5. References

[Jena]
Jena: Implementing the Semantic Web Recommendations, Jeremy Carroll et all, http://www.hpl.hp.com/techreports/2003/HPL-2003-146.html
[JenaDB]
Efficient RDF Storage and Retrieval in Jena2 , Kevin Wilkinson et all, http://www.hpl.hp.com/techreports/2003/HPL-2003-266.html
[RDQL]
RDQL - A Query Language for RDF, Andy Seaborne, W3C Member Submission, http://www.w3.org/Submission/2004/SUBM-RDQL-20040109/
[Joseki]
Joseki - the Jena RDF Server, Andy Seaborne,http://www.joseki.org/
[D2R]
D2R MAP - A Database to RDF Mapping Language, Christian Bizer, http://www.wiwiss.fu-berlin.de/suhl/bizer/pub/www2003-D2R-Map.pdf
[RDF2SQL]
RDF to SQL Mapping, Eric Prud'hommeaux, http://www.w3.org/2003/01/21-RDF-RDB-access/
 
[RDF-SYNTAX]
RDF/XML Syntax Specification (Revised), Beckett D. (Editor), W3C Recommendation, http://www.w3.org/TR/rdf-syntax-grammar/
[DAWG]
W3C Data Access Working Group Website: http://www.w3.org/2001/sw/DataAccess/


6. Change Log