Background
We have been developing solutions for our clients lately that involve loading an ontology into a triple store, and building a UI for data entry. One of the challenges is how to handle renaming things. If you want to change the URI of a class or property in Protégé you load all the ontologies and datasets that use the old URI and use the rename entity command in the Refactor menu. Like magic, and all references to the URI are changed with the press of the Enter key. In a triple store, it is not so easy. You have to track down and change all the triples that refer to the old URI. This means writing and executing SPARQL queries using INSERT
and DELETE
to make changes in place. Below is an outline of how to rename a class.
Steps of Change
Let ?oldClass
and ?newClass
be variables bound to the URI for the old and new classes respectively – e.g. ?oldClass
might be veh:Auto
and ?newClass
might be veh:Car
. The class rename operation involves the following steps:
- Change all instances of
?oldClass
to be instances of?newClass
instead. e.g.
veh:myTeslaS rdf:type veh:Auto
is replaced with
veh:myTeslaS rdf:type veh:Car
- Find and examine all the triples using ?
oldClass
as the object. It may occur in triples where the subject is a blank node and the predicate is one of the several used for defining OWL restrictions. E.g ._:123B456x78 owl:someValuesFrom veh:Auto
Replace triples with the old class URI in the object with new triples using the new URI. Note, you might want to do the first part of the next step before doing the replace. - Find and examine all the triples using
?oldClass
as the subject. It may occur in triples for declaring subclass relationships, comments as well as the triple creating the class in the first place. e.g.veh:Auto rdf:type owl:Class
Replace triples with the old class URI in the subject with new triples using the new URI. - Look around for anywhere else that the old name may be used. Possibilities include:
- If your instances use a naming convention that includes the name of the class (e.g.
veh:Auto_234
)then you will have to find all the URIs that start withveh:_Auto
and useveh:_Car
instead. We will look into this in a future blog. - The class name may occur in comment strings and other documentation.
- It may also be used in SPARQL queries that are programmatically called.
- If your instances use a naming convention that includes the name of the class (e.g.
Here is some SPARQL for how to do to the first step.
# Rename class veh:Auto to veh:Car # For each ?instance of ?oldClass # Replace the triple <?instance rdf:type ?oldClass> # with <?instance rdf:type ?newClass> DELETE {?instance rdf:type ?oldClass} INSERT {?instance rdf:type ?newClass} WHERE {BIND (veh:Auto as ?oldClass) BIND (veh:Car as ?newClass) ?instance rdf:type ?oldClass . }
Gotchas
There are many ways to make mistakes here. Watch for the following:
- Having the
DELETE
before theINSERT
seems wrong, fear not, it is just an oddity in the SPARQL syntax. - Save out a copy of the triple store, in case things go wrong that are hard to undo. One way to do this is to make all the changes to a copy of the triple store before making them in the production one. Do all the steps, make sure things worked.
- Make sure your namespaces are defined.
- Before you make a change in place using
INSERT
andDELETE
, always useCONSTRUCT
to see what new triples will be created. - Think about the order in which you replace triples. You can easily end up replacing triples in one step, that you needed to find the triples to replace in the next step.
- Always check the total count of triples before and after an operation that replaces triples. Generally it should be the same; track down any exceptions. The count may be less due to duplicate triples that may occur in different named graphs.
- A cautious approach would be to first insert the new triples and on a second step remove the old ones. I tried this and it did not work, it seems like a bug. Throw caution to wind, and do the delete and insert at once. You have a backup, and once you get the hang of it, the extra step will just be extra work.
- It may not be possible to fully automate changes in comments and SPARQL queries that are used programmatically. Check to see what needs to change, and what doesn’t.
What Next?
After you get step 1 working, try out steps 2 and 3 on your own, all you need to do is some straight-forward modifications to the above example. Step 4 involves more exploration and custom changes.
In an upcoming blog, we explore one of those changes. Specifically, if your naming convention for instances uses the class name in the URI then those instance URIs will have to change (e.g. from veh:_Auto_2421
to veh:_Car_2421
).