Sesame API Tutorial

From Blazegraph
Jump to: navigation, search

Blazegraph™ implements Storage and Inference Layer (SAIL) Sesame API.

Creating a repository

The following code snippet creates a Sesame native repository:

import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.config.RepositoryConfig;
import org.openrdf.repository.config.RepositoryConfigException;
import org.openrdf.repository.manager.LocalRepositoryManager;
import org.openrdf.repository.sail.config.SailRepositoryConfig;
import org.openrdf.sail.config.SailImplConfig;
import org.openrdf.sail.nativerdf.config.NativeStoreConfig;
...
		String baseDirName = "./sesame/";
		LocalRepositoryManager manager = new LocalRepositoryManager(new File(baseDirName));
		manager.initialize();
		SailImplConfig nativeConfig = new NativeStoreConfig("spoc,posc,opsc");
		// create a configuration for the repository implementation
		SailRepositoryConfig repositoryTypeSpec = new SailRepositoryConfig(nativeConfig);
		RepositoryConfig repConfig = new RepositoryConfig("test", repositoryTypeSpec);
		manager.addRepositoryConfig(repConfig);
		Repository repository = manager.getRepository("test");
		repository.initialize();

Creation of a similar repository object using Blazegraph native classes:

// Blazegraph uses Sesame API interface for Repository object
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryException;
// Blazegraph implementations of Sesame API intergaces
import com.bigdata.rdf.sail.BigdataSail;
import com.bigdata.rdf.sail.BigdataSailRepository;
...
		String baseDirName = "./blazegraph/";
		Properties properties = new Properties();
		Path baseDir = Paths.get(baseDirName).toAbsolutePath();
		Path journalPath = baseDir.resolve("test.jnl");
		properties.put(BigdataSail.Options.BUFFER_MODE, "DiskRW");
		properties.put(BigdataSail.Options.FILE, journalPath.getFileName().toString());
		final BigdataSail sail = new BigdataSail(properties);
		final Repository repository = new BigdataSailRepository(sail);
		repository.initialize();

Opening a connection

Opening a connection is similar in native Sesame and Blazegraph implementation:

		RepositoryConnection connection = repository.getConnection();
		try {
		// use connection
		} finally {
			connection .close();
		}

You can also open a Blazegraph connection in read-only mode if needed:

		if (repository instanceof BigdataSailRepository) {
			connection = ((BigdataSailRepository) repository).getReadOnlyConnection();
		} else {
			connection = repository.getConnection();
		}

RDF: URIs, Literals, Statements

Model API provides a collection of java objects, representing Resource Definition Framework concepts. Blazegraph implementations could be found in com.bigdata.rdf.model package.

A Value interface is used to represent a generic RDF entity, which could be either Resource, or Literal:

URI uri = new URIImpl("uri:sample");

Blazegraph URI implementation:

URI uri = new BigdataURIImpl("uri:sample");

Also, there is a generic method for creating URI using a value factory, which depends on the provided connection:

URI uri = connection.getValueFactory().createURI("uri:sample");
BNode bNode = conn.getValueFactory().createBNode();

Although, there are direct constructors (new BNodeImpl(), new BigdataBNodeImpl()), it is recommended to use the value factory method. Due to the nature of blank nodes: they need internal identifiers specific to storage representation, which could be used only to check if the blank nodes are equal.

  • A Literal is a specific type of Value, which represent one of the basic data types:
Value literal = new LiteralImpl("1", XMLSchema.INT);

Literals also have low level internal representation specific to backing storage, so it's recommended to create them using value factory methods:

Value literal = conn.getValueFactory().createLiteral(1);

A Statement is an ordered triple of:
subject (Resource), predicate (URI) and object (Value).
It could be created using a constructor:

Statemtent stmt = new StatementImpl(subject, predicate, object);

There is also a Blazegraph implementation of a Statement interface: BigdataStatementImpl. Usually you will get such instances as a result of a query execution, there is no need to create them directly.
Just use value factory method:

Statemtent stmt = conn.getValueFactory().createStatement(subject, predicate, object);

Adding data to a repository

The basic method of adding a statement to a repository is the same in native Sesame and in Blazegraph implementations:

   conn.add(stmt);

To provide fault tolerance and to increase loading speed, you need to open a transaction:

try {
   conn.begin();
   for (...) {
      conn.add(stmt);
   }
   // Commit the result
   conn.commit();
}
catch (RepositoryException e) {
   // Roll back any changes if an error arised
   conn.rollback();
}

Batch loading of triples from file or URL resources is also available:

   conn.add(new File("data.rdf"), "base:", RDFFormat.RDFXML);
   conn.add(new File("data.n3"), "base:", RDFFormat.N3);

   conn.add(new URL("http://somedomain.com/data.nt"), "http://somedomain.com/", RDFFormat.NT);

Querying a repository

The easiest way to get raw data from the repository is to iterate statements using an SPO mask:

// getting all statements with subject s and any predicate and object (note null parameters)
RepositoryResult<Statement> statements = conn.getStatements(s, null, null, true);
try {
   while (statements.hasNext()) {
      Statement stmt = statements.next();
      Value p = stmt.getPredicate();
      Value o = stmt.getObject();
      // process
   }
} finally {
   statements.close(); // always close result to release associated resources
}

SPARQL query executions provide the most flexible and convenient way to retrieve information from the repository:

	  String queryString = "SELECT ?p ?o WHERE { <uri:example> ?p ?o } ";
	  TupleQuery tq = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
	  TupleQueryResult tqr = tupleQuery.evaluate();
	  try {
              while (tqr.hasNext()) {  // iterate over the result solutions
			BindingSet bs = tqr.next();
			Value p = bs.getValue("p");
			Value o = bs.getValue("o");
			// process...
              }
	  } finally {
	      tqr.close(); // always close result to release associated resources
	  }

Also, there are other types of queries available in the package org.openrdf.query. One of the available queries is Graph Query which can be used to retrieve a subgraph of the repository. Another query is Boolean Query which is used to check a given condition over data in the repository.