This chapter discusses the following topics related to using the Java Client API to load semantic triples, manage semantics graphs, and query semantic data. The following topics are covered:
This chapter focuses on details specific to using the Java Client API for semantic operations. For more details and general concepts, see the Semantics Developer's Guide.
The graph management capabilities of the Java Client API enable you to manipulate managed triples stored in MarkLogic. For example, you can create, modify, or delete a graph using a GraphManager. For details, see Creating and Managing Graphs.
You can insert unmanaged triples into MarkLogic using standard document operations. Use the DocumentManager
interfaces to insert XML or JSON documents with triples embedded in them. Unmanaged triples are indexed and searchable, just like managed triples, but you use typical XML and JSON document permissions and interfaces to control them. Unmanaged triples enable you to store semantic data alongside the content to which it applies. Example: Loading, Managing, and Querying Triples illustrates the use of an unmanaged triple.
Triples can also be made available for queries through the use of MarkLogic features such as the following. See the listed topics for details.
You can use the Java Client API to query all types of semantic data using the SPARQLQueryManager
interface. You can evaluate both SPARQL and SPARQL Update queries. For more details, see Querying Semantic Triples With SPARQL and Using SPARQL Update to Manage Graphs and Graph Data.
You can use the SPARQL, semantic query, and semantic graph interfaces of MarkLogic
The following table lists some common tasks related to Semantics, along with the interfaces best suited for completing the task using the Java Client API. For a complete list of interfaces, see Java Client API Documentation. All of the following interfaces are in the package com.marklogic.client.semantics
.
If you want to | Then use |
---|---|
Load semantic triples into a named graph or the default graph without using SPARQL Update. |
For details, see Creating or Overwriting a Graph. |
Manage graphs or graph data with SPARQL Update. |
For details, see Using SPARQL Update to Manage Graphs and Graph Data. |
Read a semantic graph from the database. |
For details, see Reading Triples from a Graph. |
Query semantic data with SPARQL |
For details, see Querying Semantic Triples With SPARQL. |
Manage graph permissions. | GraphManager.deletePermissions For details, see Managing Permissions. |
Use the GraphManager
interface to perform graph management tasks such as creating, reading, updating, and deleting graphs. This section contains the following topics related to graph management tasks:
The following table summarizes key GraphManager
methods. For a complete list of methods, see the Java Client API Documentation.
GraphManager Method | Description |
---|---|
Create or overwrite a graph. If the graph already exists, the effect is the same as removing the graph and then recreating it from the input data. For details, see Creating or Overwriting a Graph. | |
Retrieve triples from a specific graph. For details, see Reading Triples from a Graph. | |
Remove triples from all graphs, and then insert the quads in the input data set. Unmanaged triples are not affected. The effect is the same as first calling GraphManager.deleteGraphs , and then inserting the quads. For details, see Replacing Quad Data in Graphs. |
|
Add triples to a named graph or the default graph. If the graph does not exist, it is created. For more details, see Adding Triples to an Existing Graph. | |
Add quads to the graphs specified in the input quad data. Any graphs that do not already exist are created. Adding Triples to an Existing Graph | |
delete | Delete a specific graph. Deleting a Graph. |
deleteGraphs | Delete all graphs. Unmanaged triples are not affected. For details, see Deleting a Graph. |
Manage graph permissions. You can also set graph permissions during write and merge operations. For details, see Managing Permissions. |
Operations on graphs, such as loading triples and reading a graph, require a com.marklogic.client.semantics.GraphManager
object. To create a GraphManager
, use DatabaseClient.newGraphManager
.
For example, the following code snippet creates a DatabaseClient
, and then uses it to create a GraphManager
.
import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClient.DigestAuthContext; import com.marklogic.client.semantics.GraphManager; ... DatabaseClient client = DatabaseClientFactory.newClient( "localhost", 8000, "myDatabase", new DigestAuthContext("username", "password")); GraphManager gmgr = client.newGraphManager();
You do not have to create a new DatabaseClient
object to create a GraphManager
. You can re-use any client object previously created by your application that represents the desired connection to MarkLogic.
When reading and writing triples, you must specify the triples format MIME type. You can specify the format in the following ways:
withMimeType
method on your triples Handle
to set the format on a per source basis. For example, the following code initializes a FileHandle
for reading triples in Turtle format:import com.marklogic.client.io.FileHandle; ... FileHandle fileHandle = new FileHandle(new File("example.ttl")) .withMimetype(RDFMimeTypes.TURTLE);
GraphManager.setDefaultMimeType
to set a format to be used across all operations performed through a given GraphManager
. For example, the following code sets the default MIME type to Turtle:import com.marklogic.client.io.FileHandle; ... GraphManager graphMgr = ...; graphMgr.setDefaultMimeType(RDFMimeTypes.TURTLE);
Setting a default MIME type frees you from setting the MIME type on every triples handle and enables use of the GraphManager.*As
methods, such as GraphManager.writeAs
and GraphManager.readAs
. For example:
graphMgr.setDefaultMimeType(RDFMimeTypes.TURTLE); ... graphMgr.writeAs( someGraphURI, new FileHandle(new File("example.ttl")));
Set the MIME type to one of the values exposed by the RDFMimeTypes
class, such as RDFMimeTypes.RDFJSON
or RDFMimeTypes.TURTLE
. For more details about triples formats accepted by MarkLogic, see Supported RDF Triple Formats in Semantics Developer's Guide.
To learn more about Handles, see Using Handles for Input and Output.
Use GraphManager.write
and GraphManager.writeAs
to create or overwrite a graph. If a graph already exists with the specified URI, the effect is the same as removing the existing graph and then recreating it f rom the input triple data.
Note that if you use GraphManager.write
to load quads, any graph URI in a quad is ignored in favor of the graph URI parameter passed into write
.
For example, the following code loads triples from a file into a graph. For the complete example, see Example: Loading, Managing, and Querying Triples.
public static void loadGraph(String filename, String graphURI, String format) { System.out.println("Creating graph " + graphURI); FileHandle tripleHandle = new FileHandle(new File(filename)).withMimetype(format); graphMgr.write(graphURI, tripleHandle); }
Use the following procedure to load semantic triples into a graph in MarkLogic.
com.marklogic.client.semantics.GraphManager
. as described in Creating a GraphManager Object. For example:GraphManager graphMgr = client.newGraphManager();
Handle
associated with the input triples. The Handle
type depends on the source for your content, such as a file or in-memory data. For example, the following Handle can be used to read triples in Turtle format from a file:FileHandle tripleHandle = new FileHandle(new File("example.ttl"));
GraphManager
, specify the triples format for the Handle
, using the withMimetype
method. For more details, see Querying Semantic Triples With SPARQL. For example:tripleHandle.withMimeType(RDFMimeTypes.TURTLE);
GraphManager.write
. For example:graphMgr.write(someGraphURI, tripleHandle);
GraphManager.DEFAULT_GRAPH
as the graph URI parameter. For example:graphMgr.write(GraphManager.DEFAULT_GRAPH, tripleHandle);
DatabaseClient
object's release()
method.client.release();
As an alternative to GraphManager.write
, if you already have triples in an in-memory object, you can use GraphManager.writeAs
to short circuit explicit creation of a handle. For example:
graphManager.setDefaultMimeType(RDFMimeTypes.RDFJSON); ... Object graphData = ...; graphMgr.writeAs(someGraphURI, graphData);
For more details on this technique, see Shortcut Methods as an Alternative to Creating Handles.
Use GraphManager.read
or GraphManager.readAs
to read the contents of a graph in MarkLogic. You must specify the serialization format from the triples, either on the read Handle or the GraphManager; for details, see Specifying the Triple Format.
The following example retrieves the contents of the default graph, in Turtle format and makes the results available to the application through a StringHandle
:
StringHandle triples = graphMgr.read( GraphManager.DEFAULT_GRAPH, new StringHandle().withMimetype(RDFMimeTypes.TURTLE)); //...work with the triples as one big string
For a complete example, see Example: Loading, Managing, and Querying Triples.
Use GraphManager.replaceGraphs
and GraphManager.replaceGraphsAs
to remove all quads from all graphs and then insert quad data into the graphs specified in the new quads. Unmanaged triples are not affected by this operation. The end result is the same as first calling GraphManager.delete
(or deleteAs
) and then inserting the quads.
The quad data can be in either NQuad or TriG format. Set the MIME type appropriate, as described in Specifying the Triple Format.
The following example adds a single triple in Turtle format to the default graph. This triple is passed via a StringHandle
.
StringHandle quadHandle = new StringHandle() .with(someQuadData) .withMimetype(RDFMimeTypes.NQUAD); graphMgr.replaceGraphs(quadHandle);
The following example performs a similar operation, using replaceAs
:
graphMgr.setDefaultMimeType(RDFMimeTypes.NQUAD); ... File graphData = new File(filename); graphMgr.replaceGraphsAs(graphData);
Use GraphManager.merge
or GraphManager.mergeAs
to merge triples into an existing graph. You must specify the serialization format from the triples, either on the read Handle or the GraphManager; for details, see Specifying the Triple Format.
For quad data, use mergeGraphs
or mergeGraphsAs
. For details, see Adding Quads into an Existing Graph.
The following example adds a single triple in Turtle format to the default graph. This triple is passed via a StringHandle
.
StringHandle stringHandle = new StringHandle() .with("<http://example.org/subject2> " + "<http://example.org/predicate2> " + "<http://example.org/object2> .") .withMimetype(RDFMimeTypes.TURTLE); graphMgr.merge("myExample/graphUri", stringHandle);
The following example performs a similar operation, using mergeAs
:
graphMgr.setDefaultMimeType(RDFMimeTypes.TURTLE); ... Object graphData = ...; graphMgr.mergeAs(someGraphURI, graphData);
Use GraphManager.mergeGraphs
and GraphManager.mergeGraphsAs
to add quads to an existing graph. If a quad specifies the URI of an existing graph, the quad data is merged into that graph. If no such graph exists, the graph is created.
The quad data can be in either NQuad or TriG format. Set the MIME type appropriate, as described in Specifying the Triple Format.
The following example adds a single triple in Turtle format to the default graph. This triple is passed via a StringHandle
.
StringHandle quadHandle = new StringHandle() .with(someQuadData) .withMimetype(RDFMimeTypes.NQUAD); graphMgr.mergeGraphs(quadHandle);
The following example performs a similar operation, using mergeAs
:
graphMgr.setDefaultMimeType(RDFMimeTypes.NQUAD); ... File graphData = new File(filename); graphMgr.mergeGraphsAs(graphData);
Use GraphManager.delete to remove a single graph. Use GraphManager.deleteGraphs to delete all graphs.
The following example removes a single graph with the specified URI:
graphMgr.delete(someGraphURI);
The following example removes all graphs:
graphMgr.deleteGraphs(someGraphURI);
For a complete example, see Example: Loading, Managing, and Querying Triples.
To query semantic data using SPARQL, create a SPARQLQueryDefinition
, and then evaluate it using one of the SPARQLQueryManager.execute*
methods. You can configure many aspects of your query, such as variable bindings, the graphs to which to apply the query, the query optimization level.
Evaluating a SPARQL query consists of the following basic steps:
DatabaseClient.newSPARQLQueryManager
. For example:DatabaseClient client = ...; SPARQLQueryManager sqmgr = client.newSPARQLManager();
SPARQLQueryManager.newSPARQLQueryDefinition
and configure the query as needed. For example:SPARQLQueryDefinition query = sqmgr.newSPARQLQueryDefinition( "SELECT * WHERE { ?s ?p ?o } LIMIT 10") .withBinding("o", "http://example.org/object1");
execute*
methods of SPARQLQueryManager
. For example, use executeSelect
for a SELECT query:JacksonHandle results = new JacksonHandle(); results.setMimetype(SPARQLMimeTypes.SPARQL_JSON)); results = sqmgr.executeSelect(query, results);
The format of the results you receive depends on the type of query you evaluate and how you configure your results Handle and/or the SPARQLQueryManager. For details, see Handling Query Results.
For example, the following evaluates a SPARQL SELECT query and returns the results as JSON. For a complete example, see Example: Loading, Managing, and Querying Triples.
SPARQLQueryManager qm = client.newSPARQLQueryManager(); SPARQLQueryDefinition query = qm.newQueryDefinition( "SELECT ?person " + "WHERE { ?person <http://example.org/marklogic/predicate/livesIn> \"London\" }" ); JsonNode results = qm.executeSelect(query, new JacksonHandle()).get(); // ... Process results
The layout and available format of the results from a SPARQL query depend on the type of query. For details, see the following topics:
A SPARQL SELECT query returns a SPARQL result set, serialized as JSON, XML, or plain text comma-separated values (CSV). You must set the MIME type on your results ReadHandle as appropriate for the results format you want to use. The supported MIME types for a SELECT query are defined by com.marklogic.client.semantics.SPARQLMimeTypes
.
For example, JacksonHandle
implements SPARQLResultsReadHandle
and JSONReadHandle
, so you should set the handle MIME type to SPARQLMimeTypes.SPARQL_JSON
when receiving SELECT query results through a JacksonHandle
:
JacksonHandle handle = new JacksonHandle(); handle.setMimeType(SPARQLMimeTypes.SPARQL_JSON);
The following table summarizes the supported Handle and MIME type combinations:
Handle Type | MIME Type | Result |
---|---|---|
JSONReadHandle | SPARQLMimeTypes.SPARQL_JSON | SPARQL results, serialized as JSON. For details on this format, see https://www.w3.org/TR/sparql11-results-json/. |
XMLReadHandle | SPARQLMimeTypes.SPARQL_XML | SPARQL results, serialized as XML. For details on this format, see https://www.w3.org/TR/2013/REC-rdf-sparql-XMLres-20130321/. |
Other Handle types | SPARQLMimeTypes.SPARQL_CSV | SPARQL results, serialized as CSV, with line per query solution. For details on this format, see https://www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/. |
For examples of the raw XML, JSON, and CSV results, see the examples in Response Output Formats in the Semantics Developer's Guide.
CONSTRUCT and DESCRIBE queries return triples. You can request the results in any of the triples formats defined by com.marklogic.client.semantics.RDFMimeTypes
, except TRIG. For best performance, use the N-triples format (RDFMimeTypes.NTRIPLES
).
When using a JSONReadHandle,
set the handle MIME type to RDFMimeTypes.RDF_JSON
. This produces results in RDF/JSON format.
When using an XMLReadHandle,
set the handle MIME type to RDFMimeTypes.RDF_XML
. This produces results in RDF/XML format.
Any TriplesReadHandle implementation that handle plain text can use any of the RDFMimeTypes, such as NTRIPLE
, NQUADS
, or TURTLE
.
For RDF/XML. use an XMLReadHandle
with the MIME type set to RDFMimeTypes.RDF_XML
.
To set the handle MIME type, use the setMimeType
method. For example:
JacksonHandle handle = new JacksonHandle(); handle.setMimeType(RDFMimeTypes.RDFJSON);
An ASK query always returns a simple boolean value. For details, see QueryManager.executeAsk
.
If your query depends on runtime variable definitions, you can define variable bindings one at a time using the fluent SPARQLQueryDefinition.withBinding
definition, or build up a set of bindings using SPARQLBindings
and then attach them to the query using SPARQLQueryDefinition.setBindings
.
The following example incrementally attaches bindings to a query definition using withBindings:
// incrementally attach bindings to a query SPARQLQueryDefinition query = ...; query.withBinding("o", "http://example.org/object1") .withBinding(...);
The following example builds up a setting of bindings and then attaches them all to the query at once, using setBindings:
// build up a set of bindings and attach them to a query SPARQLBindings bindings = new SPARQLBindings(); bindings.bind("o", "http://example.org/object1"); bindings.bind(...); query.setBindings(bindings);
Both SPARQLQueryDefinition.withBinding
and SPARQLBindings
enable you to specify a language tag or RDF type for the bound value.
For more details, see SPARQLBindings in the Java Client API Documentation.
When you evaluate a SPARQL SELECT
query, by default, all results are returned. You can limit the number of results returned in a page using SPARQLQueryManager.setPageLength
or a SPARQL LIMIT
clause. You can retrieve successive pages of results by repeatedly calling executeSelect
with a different page start position. For example:
// Change the max page length sqmgr.setPageLength(NRESULTS); // Fetch at most the first N results long start = 1; JacksonHandle results = sparqlMgr.executeSelect(query, handle, start); // Fetch the next N results start += N; JacksonHandle results = sparqlMgr.executeSelect(query, handle, start);
Inferencing enables discovery of new facts based on a combination of data and rules for understanding that data. The Java Client API includes the following features that facilitate inferencing:
When automatic inferencing is enabled, MarkLogic can apply a default inferencing ruleset at query time. Default ruleset management is a function of the REST Management API. However, you can enable or disable the use of a default ruleset at query time using SPARQLQueryDefinition.withIncludeDefaultRulesets
. Use of the default ruleset is enabled by default.
For more details, see Rulesets in the Semantics Developer's Guide.
You can explicitly apply a ruleset at query time rather than implicitly using the default ruleset.
The Java Client API includes the com.marklogic.client.semantics.SPARQLRuleset
class with a set of built-in rulesets and a factory method to enable you to use custom rulesets. To associate a ruleset with a query, use SPARQLQueryDefinition.withRuleset
or SPARQLQueryDefinition.setRulesets.
For more details, see Rulesets in the Semantics Developer's Guide.
The Optic features of the Java Client API enable you to query semantic data without using SPARQL. The Optic features of the Java Client API are covered in detail in Optic Java API for Relational Operations.
To perform a semantic query using the Optic API, construct a query plan using com.marklogic.client.expression.PlanBuilder
, and then evaluate it using com.marklogic.client.row.RowManager
. For example, the following function creates a query plan that finds persons who live in London, based on the data from Example: Loading, Managing, and Querying Triples.
public static void opticQuery() { RowManager rowMgr = client.newRowManager(); PlanBuilder p = rowMgr.newPlanBuilder(); PlanPrefixer predPrefixer = p.prefixer("http://example.org/marklogic/predicate/"); Plan plan = p.fromTriples( p.pattern(p.col("person"), predPrefixer.iri("livesIn"), p.xs.string("London"))); RowSet<RowRecord> results = rowMgr.resultRows(plan); System.out.println("OPTIC: Persons who live in London:"); for (RowRecord row: results) { System.out.println(" " + row.getString("person")); } }
When the above function runs as part of the end to end example, it produces output of the following form:
OPTIC: Persons who live in London: http://example.org/marklogic/person/Jane_Smith http://example.org/marklogic/person/John_Smith http://example.org/marklogic/person/Mother_Goose
The following example program demonstrates how to perform the following tasks:
This example creates a graph from the following input data. Copy and paste this data to a file, and then modify the variable tripleFilename
in the example code to point to this file.
<http://example.org/marklogic/person/John_Smith> <http://example.org/marklogic/predicate/livesIn> "London"^^<http://www.w3.org/2001/XMLSchema#string> . <http://example.org/marklogic/person/Jane_Smith> <http://example.org/marklogic/predicate/livesIn> "London"^^<http://www.w3.org/2001/XMLSchema#string> . <http://example.org/marklogic/person/Jack_Smith> <http://example.org/marklogic/predicate/livesIn> "Glasgow"^^<http://www.w3.org/2001/XMLSchema#string> .
The example data contains triple data that define relationships of the form Person X livesIn Y. The query run by the example finds all persons who live in London. The program runs the query several times:
The example code demonstrates how to use a SPARQL query and an Optic query to fetch the same information. For more details, see Querying Semantic Triples With SPARQL and Querying Triples with the Optic API.
Before running the following program, modify the definition of the client
and tripleFilename
variables to match your environment.
package examples; import java.io.File; import com.fasterxml.jackson.databind.JsonNode; import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.document.JSONDocumentManager; import com.marklogic.client.expression.PlanBuilder; import com.marklogic.client.expression.PlanBuilder.Plan; import com.marklogic.client.io.FileHandle; import com.marklogic.client.io.Format; import com.marklogic.client.io.JacksonHandle; import com.marklogic.client.io.StringHandle; import com.marklogic.client.row.RowManager; import com.marklogic.client.row.RowRecord; import com.marklogic.client.row.RowSet; import com.marklogic.client.semantics.GraphManager; import com.marklogic.client.semantics.RDFMimeTypes; import com.marklogic.client.semantics.SPARQLQueryDefinition; import com.marklogic.client.semantics.SPARQLQueryManager; import com.marklogic.client.type.PlanPrefixer; public class Graphs { static DatabaseClient client = DatabaseClientFactory.newClient( "localhost", 8000, "Documents", new DatabaseClientFactory.DigestAuthContext( "username", "password")); static private GraphManager graphMgr = client.newGraphManager(); static private String graphURI = GraphManager.DEFAULT_GRAPH; static private String tripleFilename = "/path/to/your/file.ttl"; static private String unmanagedTripleDocURI = "mothergoose.json"; // Load managed triples from a file into a graph in MarkLogic public static void loadGraph(String filename, String graphURI, String format) { System.out.println("Creating graph " + graphURI); FileHandle tripleHandle = new FileHandle(new File(filename)).withMimetype(format); graphMgr.write(graphURI, tripleHandle); } // Insert a document that includes an unmanaged triple. public static void addUnmanagedTriple() { System.out.println("Inserting doc containing an unmanaged triple..."); StringHandle contentHandle = new StringHandle( "{ \"name\": \"Mother Goose\"," + "\"triple\" : {" + "\"subject\" : \"http://example.org/marklogic/person/Mother_Goose\"," + "\"predicate\" : \"http://example.org/marklogic/predicate/livesIn\"," + "\"object\" : {" + "\"value\" : \"London\"," + "\"datatype\" : \"http://www.w3.org/2001/XMLSchema#string\"" + "} } }").withFormat(Format.JSON); JSONDocumentManager jdm = client.newJSONDocumentManager(); jdm.write(unmanagedTripleDocURI, contentHandle); } public static void deleteUnmanagedTriple() { System.out.println("Removing doc containing unmanaged triple..."); JSONDocumentManager jdm = client.newJSONDocumentManager(); jdm.delete(unmanagedTripleDocURI); } public static void readGraph(String graphURI, String format) { System.out.println("Reading graph " + graphURI); StringHandle triples = graphMgr.read(graphURI, new StringHandle().withMimetype(format)); System.out.println(triples); } // Delete a graph. Unmmanaged triples are unaffected. public static void deleteGraph(String graphURI) { System.out.println("Deleting graph " + graphURI); graphMgr.delete(graphURI); } // Evaluate a SPARQL query. public static void sparqlQuery() { SPARQLQueryManager qm = client.newSPARQLQueryManager(); SPARQLQueryDefinition query = qm.newQueryDefinition( "SELECT ?person " + "WHERE { ?person <http://example.org/marklogic/predicate/livesIn> \"London\" }" ); JsonNode results = qm.executeSelect(query, new JacksonHandle()).get(); JsonNode matches = results.path("results").path("bindings"); System.out.println("SPARQL: Persons who live in London:"); for (int i = 0; i < matches.size(); i++) { String subject = matches.get(i).path("person").path("value").asText(); System.out.println(" " + subject); } } public static void opticQuery() { RowManager rowMgr = client.newRowManager(); PlanBuilder pb = rowMgr.newPlanBuilder(); PlanPrefixer predPrefixer = pb.prefixer("http://example.org/marklogic/predicate/"); Plan plan = pb.fromTriples( pb.pattern( pb.col("person"), predPrefixer.iri("livesIn"), pb.xs.string("London"))); RowSet<RowRecord> results = rowMgr.resultRows(plan); System.out.println("OPTIC: Persons who live in London:"); for (RowRecord row: results) { System.out.println(" " + row.getString("person")); } } public static void main(String[] args) { loadGraph(tripleFilename, graphURI, RDFMimeTypes.TURTLE); readGraph(graphURI, RDFMimeTypes.TURTLE); // Query the graph for persons who live in London. // Should find 2 matches. sparqlQuery(); // Add a document containing an unmanaged triple. Query again. // Should find 3 matches. addUnmanagedTriple(); sparqlQuery(); // Perform the same query using the Optic API opticQuery(); // Delete the created graph. Unmanaged triple remains. // Query should find 1 match. deleteGraph(graphURI); sparqlQuery(); // Remove the document containing the unmanaged triple. // Query should find no matches. deleteUnmanagedTriple(); sparqlQuery(); client.release(); } }
When you run the example, you should see output similar to the following. Whitespace has been added to the output to more easily distinguish between the operations.
Creating graph com.marklogic.client.semantics.GraphManager.DEFAULT_GRAPH @prefix p1: <http://example.org/marklogic/predicate/> . @prefix p0: <http://example.org/marklogic/person/> . p0:Jane_Smith p1:livesIn "London" . p0:Jack_Smith p1:livesIn "Glasgow" . p0:John_Smith p1:livesIn "London" . SPARQL: Persons who live in London: http://example.org/marklogic/person/Jane_Smith http://example.org/marklogic/person/John_Smith http://example.org/marklogic/person/Mother_Goose Inserting a document containing an unmanaged triple... SPARQL: Persons who live in London: http://example.org/marklogic/person/Jane_Smith http://example.org/marklogic/person/John_Smith http://example.org/marklogic/person/Mother_Goose OPTIC: Persons who live in London: http://example.org/marklogic/person/Jane_Smith http://example.org/marklogic/person/John_Smith http://example.org/marklogic/person/Mother_Goose Deleting graph com.marklogic.client.semantics.GraphManager.DEFAULT_GRAPH SPARQL: Persons who live in London: http://example.org/marklogic/person/Mother_Goose Removing document containing unmanaged triple... SPARQL: Persons who live in London:
You can use SPARQL Update to insert, update, or delete triples and graphs, as an alternative to the graph management interface described in Creating and Managing Graphs. You cannot use SPARQL Update to operate on unmanaged triples.
To learn about SPARQL Update, see SPARQL Update in the Semantics Developer's Guide.
To use SPARQL Update with the Java Client API, follow the same procedure as for SPARQL query, but initialize your SPARQLQueryDefinition
with update rather than query code, and use SPARQLQueryManager.executeUpdate
to evaluate the update. For details, see Basic Steps for SPARQL Query Evaluation.
For example, the following code adds a single triple to the default graph. You can add this function to the example framework in Example: Loading, Managing, and Querying Triples to experiment with SPARQL Update.
public static void sparqlUpdate() { SPARQLQueryManager qm = client.newSPARQLQueryManager(); SPARQLQueryDefinition query = qm.newQueryDefinition( "PREFIX exp: <http://example.org/marklogic/people/>" + "PREFIX pre: <http://example.org/marklogic/predicate/>" + "INSERT DATA {" + " exp:Humpty_Dumpty pre:livesIn \"London\" ." + " }" ); System.out.println("Inserting a triple using SPARQL Update"); qm.executeUpdate(query); }
A successful SPARQL Update returns no results.
You can bind variables to values using the procedure described in Defining Variable Bindings.
Permissions on semantic data are managed at either the graph or document level, depending on whether the triples are managed or unmanaged. Querying and reading semantic data requires read permissions on either the containing graph (managed triples) or document (unmanaged triples).
This section covers the following topics related to controlling permissions on semantic data:
All graphs created and managed using the Java, REST, or Node.js Client APIs grant read capability to the rest-reader
role and update capability to the rest-writer
role. These default permissions are always assigned to a graph, even if you do not explicitly specify them.
If you explicitly specify other permissions when creating a graph, the default permissions are still set, in addition to the permissions you specify.
You can use custom roles to limit access to selected users on a graph by graph basis. Your custom roles must include equivalent rest-reader
and rest-writer
privileges. Otherwise, users with these roles cannot use the Java Client API to manage or query semantic data. For details, see Controlling Access to Documents and Other Artifacts in the REST Application Developer's Guide.
For more information on the MarkLogic security model, see the Security Guide.
When you create a graph with the Java Client API, MarkLogic assigns a set of default permissions, even if you do not specify any explicit permissions; for details, see Default Graph Permissions and Required Privileges. You can modify permissions on a graph as a standalone operation or as part of another operation, such as when creating or merging graphs.
Graph permissions are encapsulated in a GraphPermissions
object. To create a set of graph permissions, use GraphManager.newGraphPermissions
or GraphManager.permission
.
To modify permissions standalone, use the following GraphManager
methods:
To modify permissions as part of another operation, such as GraphManager.write
or GraphManager.merge
, include a GraphPermissions
object in your call.
The following example sets the permissions on the graph with URI myExample/graphUri. The code grants the role example_manager read and update permissions on the graph.
graphMgr.writePermissions("myExample/graphUri", graphMgr.permission("example_manager", Capability.READ) .permission("example_manager", Capability.UPDATE));
The following example sets the graph permissions as part of a graph merge operation:
graphMgr.merge( "myExample/graphUri", someTriplesHandle, graphManager.permission("role1", Capability.READ) .permission("role2", Capability.READ, Capability.UPDATE));
To retrieve permissions metadata for a named graph or the default graph, use GraphManager.getPermissions
. Explore the resulting GraphPermissions
object using Map
operations. The Map keys are role names, such as rest-reader, and the values are the capabilities.
For example, the following code fetches the permissions on the default graph and prints the capabilities associated with the rest-reader role:
GraphPermissions permissions = graphMgr.getPermissions(GraphManager.DEFAULT_GRAPH); System.out.println(permissions.get("rest-reader");
Unmanaged triples are stored in documents, alongside other content, rather than being inserted into the triple store. You control access to unmanaged triples through the permissions on the documents that contain them.
For example, a SPARQL query will only return a matching unmanaged triple if the user running the query has read permissions on the document that contains the triple.
Permissions are considered document metadata. Set permissions using the DocumentManager
interface and a MetadataHandle
. For example, set permissions using DocumentMetadataHandle.setPermissions
, and then including the metadata handle in a call to DocumentManager.write
. For more details, see Reading, Modifying, and Writing Metadata.
For more information document permissions, see Protecting Documents in the Security Guide.