Search code examples
sparqlrdf

Best approach to create URIs with Sparql (like auto increment)


I am currently writing a service which creates new items (data) by user input. To save these items in a RDF Graph Store (currently using Sesame via Sparql 1.1), I need to add a subject URI to the data. My approach is to use a number that is incremented for each new item. So e.g.:

<http://example.org/item/15> dct:title "Example Title" .
<http://example.org/item/16> dct:title "Other Item" .

What's the best approach to get an incremented number for new items (like auto incement in MySQL/MongoDB) via Sparql? Or to issue some data and the endpoint autmatically creates a URI by a template (like done for blank nodes). But I don't want to use blank nodes as subjects for these items. Is there a better solution than using an incremented number? My users don't care about the the URI.... and I don't want to handle collisions like created by hashing the data and using the hash as part of the subject.


Solution

  • If you maintain a designated counter during updates, then something along these lines will do it,

    fisrt insert a counter into your dataset

    insert data {
        graph <urn:counters> {<urn:Example> <urn:count> 1 }
    }
    

    then a typical update should looks like:

    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    delete {
        #remove the old value of the counter
        graph <urn:counters> {<urn:Example> <urn:count> ?old}
    } 
    insert {
        #update the new value of the counter
        graph <urn:counters> {<urn:Example> <urn:count> ?new}
    
        # add your new data using the constructed IRI
        GRAPH <http://example.com> {
            ?id dct:title "Example Title" ;
                a <http://example.org/ontology/Example> .
        } .
    } where {
        # retrieve the counter
        graph <urn:counters> {<urn:Example> <urn:count> ?old}
    
        # compute the new value
        bind(?old+1 as ?new)    
    
        #construct the IRI
        bind(IRI(concat("http://example.org/item/", str(?old))) as ?id)
    }