Semantic Graph Developer's Guide (PDF)

MarkLogic Server 11.0 Product Documentation
Semantic Graph Developer's Guide
— Chapter 12

« Previous chapter
Next chapter »

Inserting, Deleting, and Modifying Triples with XQuery and Server-Side JavaScript

Triples can be modified with XQuery or Server-side JavaScript, using MarkLogic xdmp built-ins. Triples managed by MarkLogic - those triples having a document root of sem:triples - can be modified using SPARQL Update. See Using SPARQL Update for more information about modifying managed triples.

Unmanaged triples, those triples embedded in another document with an element node of sem:triple, can only be modified using XQuery or Server-Side JavaScript and xdmp built-ins. To perform updates on triples in your datastore (for either managed or unmanaged triples), you insert a new triple and delete the existing one. You are not updating the existing triple; the update operation is actually an INSERT/DELETE procedure.

This chapter includes the following sections:

Updating Triples

You can use XQuery or Server-Side JavaScript functions to update existing triples in a database, by using INSERT/DELETE to replace nodes. For a managed triple, the sem:database-nodes (sem.databaseNode in Server-Side JavaScript) and the xdmp:node-replace (xdmp.nodeReplace in Server-Side JavaScript) functions are used to correct inaccurate data.

Assume the database contains a document containing the following unmanaged triple, with the resource John Doe entered as John_Doe:

<sem:triples xmlns:sem="http://marklogic.com/semantics">
 <sem:triple>
  <sem:subject>http://dbpedia.org/resource/John_Doe</sem:subject>
  <sem:predicate>http://www.w3.org/1999/02/22-rdf-syntax-ns#type</sem:predicate>
  <sem:object>http://xmlns.com/foaf/0.1/Person/</sem:object>
 </sem:triple>
</sem:triples>

The following example replaces the subject with http://dbpedia.org/resource/John_Doe using the xdmp:node-replace function. The example uses sem:rdf-builder to construct a triple that matches the one we want to change. Using this triple with sem:database-nodes finds the matching nodes in the database to be changed.

xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics" 
  at "/MarkLogic/semantics.xqy";

(: construct the triple to match against :)
let $builder := sem:rdf-builder(
  sem:prefixes("dbpedia: http://dbpedia.org/resource/"))
let $triple := $builder(
  "dbpedia:John_Doe", "a", "foaf:Person")
(: find matching unmanaged triples in the database :)
let $node := sem:database-nodes($triple)
(: construct the replacement triple with a new subject :)
let $replace := 
  <sem:triple>
    <sem:subject>http://dbpedia.org/resource/John_Doe</sem:subject>
    {$node[1]/sem:predicate, $node[1]/sem:object}
  </sem:triple>

(: replace the old triple with the new one in all matched nodes :)
return $node ! xdmp:node-replace($node, $replace);

The following example performs the same operation using Server-Side JavaScript. The example uses the NodeBuilder interface to construct the replacement node.

declareUpdate();
const sem = require('/MarkLogic/semantics');

// construct the triple to find in the database
const builder = 
  sem.rdfBuilder(sem.prefixes('dbpedia: http://dbpedia.org/resource/'));
const triple = xdmp.apply(builder, 
  'dbpedia:John_Doe', 'a', 'foaf:Person');

for (let node of sem.databaseNodes(triple)) {
  // construct the replacement triple with the new subject
  const pred = fn.head(
    node.xpath('sem:predicate', 
               {'sem': 'http://marklogic.com/semantics'}));
  const obj = fn.head(
    node.xpath('sem:object', 
               {'sem': 'http://marklogic.com/semantics'}));
  const replacement = new NodeBuilder()
    .startElement('sem:triple','http://marklogic.com/semantics/')
      .addElement(
        'sem:subject',
        'http://dbpedia.org/resource/John_Doe',
        'http://marklogic.com/semantics')
      .addNode(pred)
      .addNode(obj)
    .endElement()
    .toNode();
  // replace the old triple with the new one
  xdmp.nodeReplace(node, replacement)
}

When you have multiple triples to update, you can use XQuery or Server-Side JavaScript (or if they are managed triples, SPARQL Update), to find matching triples, and then iterate over the nodes to replace them.

In this example, a cts:triples call finds all triples with John_Doe in the subject position and replaces each occurrence with Jane_Roe:

xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics" 
  at "/Marklogic/semantics.xqy";

let $triples := cts:triples(sem:iri("http://dbpedia.org/resource/John_Doe"),(),())
for $triple in  $triples
let $node := sem:database-nodes($triple)
let $replace := 
    <sem:triple>
       <sem:subject>http://dbpedia.org/resource/Jane_Roe</sem:subject>
       {$node/sem:predicate, $node/sem:object}
    </sem:triple>
return $node ! xdmp:node-replace(., $replace)

An empty sequence is returned for both of the examples because the replacements have been made. Use a simple cts:triples call to verify that the updates have been made:

cts:triples(sem:iri("http://dbpedia.org/resource/John_Doe"),
           (),())

Using the xdmp:node-replace function results in creating a new fragment and deleting the old fragment. When the system performs a merge, the deleted fragments are removed permanently. The system performs automatic merges, unless this feature has been disabled by an administrator.

Deleting Triples

This section discusses methods for deleting RDF data in MarkLogic and includes the following topics:

Deleting Triples with XQuery or Server-Side JavaScript

There are several functions you can use to delete triples from a database. This section discusses the following functions:

sem:graph-delete

This function only works for managed triples.

You can use the sem:graph-delete function to delete all managed triple documents in a named graph. You specify the graph IRI as the parameter.

For example:

xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics" 
  at "/MarkLogic/semantics.xqy";

sem:graph-delete(sem:iri("mynamedgraph"))

In Server-Side JavaScript the command would be:

const sem = require("/marklogic/semantics.xqy");

sem.graphDelete(sem.iri("mynamedgraph"));

The following example deletes all managed triples in the default graph. If no other named graphs exist, this might remove all triples from the database:

xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics" 
  at "/MarkLogic/semantics.xqy";

sem:graph-delete(
  sem:iri("http://marklogic.com/semantics#default-graph"))

The sem:graph-delete function will only delete triples inserted by the Graph Store API, which have a document root element of sem:triple. If you delete a specific named graph, it will not affect documents with embedded triples (with a sem:triples element node), so the graph might still exist.

xdmp:node-delete

To delete a set of triples from the database, use the sem:database-nodes function with xdmp:node-delete in XQuery, or sem.databaseNodes with xdmp.nodeDelete in Server-Side JavaScript. This function works with managed or unmanaged triples.

For example:

xquery version "1.0-ml"; 
import module namespace sem = "http://marklogic.com/semantics" 
  at "/MarkLogic/semantics.xqy";

let $triples :=
cts:triples(sem:iri("http://www.rdfabout.com/rdf/usgov/congress/people
/D000596"),()())

for $triple in $triples
return (sem:database-nodes($triple) ! xdmp:node-delete(.))

This query will not delete empty sem:triple document elements if all the triples are deleted from a single document.

In Server-Side JavaScript, the example would look like this:

const sem = require('/MarkLogic/semantics');
const triples = cts.triples(
  sem.iri('http://www.rdfabout.com/rdf/usgov/congress/people/D000596'),
  null, null);

for (let triple of triples) {
  for (let node of xdm.databaseNodes(triple)) {
    xdmp.nodeDelete(node)
  }
}
xdmp:document-delete

You can remove documents containing triples from the database with the xdmp:document-delete function. This function deletes a document and all of its properties, and works with both managed and unmanaged triples. Specify the IRI of the document to be deleted as the parameter.

The following XQuery example deletes the document with URI example.xml:

xquery version "1.0-ml";
xdmp:document-delete("example.xml")

The following example performs the equivalent operation in Server-Side JavaScript:

declareUpdate();
const sem = require('/MarkLogic/semantics.xqy');

xdmp.documentDelete('example.xml');

Deleting a document deletes the document, any triples embedded in the document, and the document properties.

To delete all documents in a directory, use the xdmp:directory-delete function.

Deleting Triples with REST API

You can use the REST API to delete triples in the default graph or a named graph by sending a DELETE request to the DELETE /v1/graphs service. To delete triples from a named graph, use curl to send the DELETE request in the following form:

http://host:port/version/graphs?graph=graph-iri

where graph-iri is the IRI of your named graph.

The IRI for the named graph in the request is http://host:port/version/graphs?default. For example, this DELETE request removes all triples from the default graph at port 8321:

#Windows users, see Modifying the Example Commands for Windows 

$ curl --anyauth --user user:password -X DELETE \
http://localhost:8321/v1/graphs?default

Use caution when specifying the graph, since there is no confirmation check before deleting the dataset.

This curl command will delete the triples in the graph named mygraph.

#Windows users, see Modifying the Example Commands for Windows 

$ curl --anyauth --user user:password -X DELETE \
http://localhost:8321/v1/graphs?graph=http://marklogic.com/semantics#mygraph/

As with the sem:graph-delete function, the DELETE request removes triples from graphs where sem:triples is the root element of the containing document (managed triples). XML documents that contain embedded triples are unaffected. Graphs may still exist after the DELETE operation if the graph contained both types of documents.

When you send a PUT request, triples are replaced in a named graph or added to an empty graph if the graph did not exist. This is the equivalent of a DELETE followed by POST.

For example:

# Windows users, see Modifying the Example Commands for Windows 

$ curl --digest --user admin:password -s -X PUT 
-H "Content-type:text/turtle" --data-binary '@./example.ttl'
    "http://localhost:8033/v1/graphs?graph=mynamed-graph"

To perform the equivalent of a DELETE operation using the REST API, use curl to send a PUT request with an empty graph.

« Previous chapter
Next chapter »
Powered by MarkLogic Server | Terms of Use | Privacy Policy