remember and query do not use them yet.
POST /v1/gb/ontologies
Loads an ontology under a name.
Response
201 with the metadata of the ontology:
Errors are
{"error": "..."}. It makes no LLM call. Example, loading the bundled ontology:
PUT /v1/gb/ontologies/{name}
Updates the ontology stored undername with a new document. By default the document is merged into the stored ontology; with "replace": true it replaces it.
name comes from the path. The other fields are as for POST, plus:
Only the owner’s ontology can be updated. Response
200 with the new metadata. The ontology keeps its id, user_id, name and created_at; updated_at is set to now. Statuses are those of POST, except that there is no 409, and 404 means the user has no ontology with that name. An update never creates an ontology; use POST for that.
Merging (the default)
The document is merged into the stored ontology. A merge can add and correct things, but never deletes anything. Identity. What counts as “the same” decides what gets overwritten:- A class is identified by its IRI. Two classes with the same IRI are the same class, whatever their name, label or comment say.
- An edge is identified by its source class IRI, its target class IRI, its kind and its property IRI (for the
subclass_of,equivalent_classanddisjoint_withkinds, the RDFS/OWL predicate; see How OWL is mapped). SoTrade -hasBuyer-> Buyeris one edge, and changing its label in the document does not make a second edge. Two properties with different IRIs between the same two classes are two edges.
Why mentioned classes are not overwritten: a fragment such as “property
tradedOn from Asset to Market” has to name its endpoints, but it says nothing about them. If naming a class overwrote it, such a fragment would erase the stored label and comment of Asset and Market. So a document describes a class only by declaring it.
Overwriting changes the stored row in place and keeps its ID, so everything attached to a class (the edges that start or end at it) stays attached.
Metadata after a merge:
classes,propertiesandedgesdescribe the ontology after the merge (the totals of what is stored), not the size of the document.size_bytesandsha256describe the document of this update, the last one applied, not the merged whole. They identify what was last sent.updated_atis set.iriandtitle(from the document’sowl:Ontology, if it has one) overwrite the stored ones; if the document has none, the stored ones are kept, because a fragment usually has no header.description: the request’sdescriptionif given; otherwise the document’srdfs:comment; otherwise the stored one is kept.
replace.
Example. The stored ontology has the classes Asset and Market (with labels and comments) and the edge Asset -tradedOn-> Market (label “traded on”, inverse listsAsset). Merging this fragment:
Stock and the edge Stock -subclass_of-> Security; overwrites the edge Asset -tradedOn-> Market, which now has the label “trades on”, no comment and no inverse; leaves Asset, Market and Security as they were (they are only mentioned); and keeps everything else.
Replacing (replace: true)
The stored ontology is thrown away and the document becomes the ontology. Every stored class and edge that is not in the document is deleted, and the metadata is recomputed from the document alone, as if it had just been loaded with POST: the counts are those of the document, and description, iri and title are the document’s (the old ones are dropped, so an omitted description becomes the document’s rdfs:comment, or empty). Only the identity (id, user_id, name, created_at) is kept. Use it to remove things, or to load a new version of the whole ontology.
What is stored
Loading an ontology writes to two places. If either fails, nothing is kept and the name stays free. Updating writes to the same two places and, on failure, keeps the previous version. Within an ontology a class is identified by its IRI and an edge by (source, target, kind, IRI); this is what the unique constraints below enforce, and what a merge uses to decide what already exists. Metadata, in the relational database. One row ingb_ontologies per ontology: id, user_id, name, description, iri and title (from the document’s owl:Ontology, if any), format, size_bytes, sha256 (of the loaded document, so you can tell which version was loaded), the counts classes, properties and edges, created_at and updated_at (equal until the first update). UNIQUE (user_id, name).
The ontology itself, in the graph database. It is a small graph, separate from the dataset graph (gb_entities, gb_edges), and written in one transaction:
The graph rows reference the metadata row with
ON DELETE CASCADE. Like everything else, the SQL lives in the backends (internal/db/relational/*/db_ontology.go, internal/db/graph/*/db_ontology.go), for SQLite and PostgreSQL.
How OWL is mapped
The document must be OWL in RDF/XML. The parser (internal/ontology) is a small RDF/XML reader plus an interpretation of the OWL terms below; it has no external dependencies.
In every edge,
iri is the IRI of the property (or, for the first three rows, of the RDFS/OWL predicate). Within an ontology, classes are identified by IRI; name is only the readable local name.
Not stored: anything else, in particular restrictions and other anonymous class expressions, owl:intersectionOf, datatype and annotation properties, individuals, rdfs:subPropertyOf, properties missing a domain or a range, and the built-in classes (owl:Thing, …). Documents using them still load; those parts are skipped. A document that yields no class at all is rejected with 400.
The market ontology
build/ontology/market.owl is a basic, general ontology of markets with the 20 most important concepts: Market, Exchange, MarketParticipant, Buyer, Seller, Intermediary, Regulator, Asset, Commodity, Security, Currency, Derivative, Order, Trade, Price, Supply, Demand, MarketIndex, Regulation and Risk. Exchange is a kind of Market; Buyer, Seller and Intermediary are kinds of MarketParticipant; Commodity, Security, Currency and Derivative are kinds of Asset. The other relationships are object properties, for example Trade -hasBuyer-> Buyer, Order -placedBy-> MarketParticipant, Price -denominatedIn-> Currency, Derivative -underlying-> Asset, Regulator -regulates-> Market, and Asset -tradedOn-> Market (inverse of Market -listsAsset-> Asset). Add further ontologies to the build/ontology directory the same way.
Limits
- There is no endpoint yet to list, read or delete ontologies.
- A merge cannot delete a class or an edge; replace the ontology to do that.
- Updating changes the stored ontology in place; there is no version history beyond
sha256(of the last document) andupdated_at. - Only RDF/XML is read (no Turtle, JSON-LD, …), and there is no reasoning or consistency checking.
- Ontologies are not connected to datasets, and
rememberandqueryignore them.