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:
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.
This section discusses methods for deleting RDF data in MarkLogic and includes the following topics:
There are several functions you can use to delete triples from a database. This section discusses the following functions:
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.
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.
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.
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) } }
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.
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
.
# 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.