SPARQL Update

SPARQL is a powerful query language that can be used to modify and enrich linked data in the Internal Store. With SPARQL, you can generate new linked data based on existing linked data, thereby enhancing the contents of the store.

The function for using SPARQL Update can be imported as follows:

import { update } from '@triplyetl/etl/sparql'

Insert Data

Insert Data can be used to add linked data to the Internal Store. The following example adds one triple:

import { logQuads } from '@triplyetl/etl/debug'
import { Etl } from '@triplyetl/etl/generic'
import { update } from '@triplyetl/etl/sparql'

export default async function (): Promise<Etl> {
  const etl = new Etl()
  etl.use(
    update(`
base <https://triplydb.com/>
insert data { <john> <knows> <mary>. }`),
    logQuads(),
  )
  return etl
}

Debug function logQuads() prints the content of the internal store to standard output:

base <https://triplydb.com/>
<john> <knows> <mary>.

Using prefix declarations

Notice that the SPARQL Update function takes a plain string. Any typos you make in this string will only result in errors at runtime, when the query string is interpreted and executed.

One of the more difficult things to get right in a SPARQL string are the prefix declarations. We can use the prefix object to insert the correct IRI prefixes.

The following example asserts three triples, and uses the prefix object to insert the IRI prefix for Schema.org:

import { logQuads } from '@triplyetl/etl/debug'
import { Etl } from '@triplyetl/etl/generic'
import { update } from '@triplyetl/etl/sparql'
import { sdo } from '@triplyetl/vocabularies'

export default async function (): Promise<Etl> {
  const etl = new Etl()
  etl.use(
    update(`
base <https://triplydb.com/>
prefix sdo: <${sdo.$namespace}>
insert data {
  <john>
    a sdo:Person;
    sdo:children <mary>;
    sdo:gender sdo:Male.
}`),
    logQuads(),
  )
  return etl
}

This prints the following linked data to standard output:

base <https://triplydb.com/>
prefix sdo: <https://schema.org/>

<john>
  a sdo:Person;
  sdo:children <mary>;
  sdo:gender sdo:Male.

Delete Data

While there are not many uses cases for removing data from the internal store, this is an operation that is supported by the SPARQL Update standard.

The following function call removes the parent/child relationship assertion that was added to the internal store earlier:

update(`
prefix sdo: <${sdo.$namespace}>
delete data { <john> sdo:children <mary>. }`),

You can use the debug function logQuads() before and after this function call, to see the effects on the internal store.

Delete Insert Where

SPARQL Update can be used to conditionally add and/or remove linked data to/from the internal store. It uses the following keywords for this:

  • where is the condition that must be met inside the internal store. Conditions can be specified in a generic way by using SPARQL variables. The bindings for these variables are shared with the other two components.
  • delete is the pattern that is removed from the internal store. This requires that the where condition is satisfied in the internal store. Any bindings for variables that are shared between the where condition and the delete pattern are instantiated before deletion is performed. Deletion is performed before insertion.
  • insert is the pattern that is added to the internal store. This requires that the where condition is satisfied in the internal store. Any bindings for variables that are shared between the where condition and the insert pattern are instantiated before insertion is performed. Insertion is performed after deletion.

We can use this powerful combination of a where condition and a delete and insert follow-up to implement rules. For example, we may want to formalize the following rule:

Persons with at least one child and the male gender, are fathers.

At the same time, we may be restricted in the information we are allowed to publish in our linked dataset:

After fatherhood has been determined, any specific information about parent/child relationships must be removed from the internal store.

The rule can be formalized as follows:

import { logQuads } from '@triplyetl/etl/debug'
import { Etl } from '@triplyetl/etl/generic'
import { update } from '@triplyetl/etl/sparql'
import { sdo } from '@triplyetl/vocabularies'

const baseIri = 'https://triplydb.com/'
export default async function (): Promise<Etl> {
  const etl = new Etl()
  etl.use(
    update(`
base <${baseIri}>
prefix sdo: <${sdo.$namespace}>
insert data {
  <john>
    a sdo:Person;
    sdo:children <mary>;
    sdo:gender sdo:Male.
}`),
    update(`
base <${baseIri}>
prefix sdo: <${sdo.$namespace}>
delete { $person sdo:children ?child. }
insert { $person a <Father>. }
where {
  $person
    a sdo:Person;
    sdo:children ?child;
    sdo:gender sdo:Male.
}`),
    logQuads(),
  )
  return etl
}