From 20781e8a9e44e9bed5b74efe542d24c04ed0e500 Mon Sep 17 00:00:00 2001 From: yulinlina Date: Mon, 10 Aug 2026 17:50:28 +0000 Subject: [PATCH 1/2] Add graph storage backend compatibility matrix (addresses #888) --- docs/storage-backends.md | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/storage-backends.md diff --git a/docs/storage-backends.md b/docs/storage-backends.md new file mode 100644 index 00000000..689002fb --- /dev/null +++ b/docs/storage-backends.md @@ -0,0 +1,128 @@ +# Graph storage backends and feature matrix + +Semantica separates graph modeling from physical storage. LPG backends are accessed through `graph_store` adapters; RDF backends are accessed through `triplet_store` adapters. + +This page is intentionally conservative: it distinguishes between an adapter existing, a feature being generally available with that model, and a backend needing user-supplied wiring. + +## Status labels + +- `built-in`: adapter implementation exists in Semantica core. +- `tested`: covered by automated integration fixtures or tests. +- `example-only`: usable example exists, but support is not asserted by integration tests. +- `interface/BYO`: interface or integration point exists; bring your own backend wiring. + +## Adapter inventory + +| Backend | Model | Adapter | Status | Reference | +| --- | --- | --- | --- | --- | +| Neo4j | LPG | `semantica.graph_store.Neo4jGraphStore` | built-in | `cookbook/introduction/09_Graph_Store.ipynb` | +| Amazon Neptune | LPG | `semantica.graph_store.NeptuneGraphStore` | built-in | `cookbook/introduction/21_Amazon_Neptune_Store.ipynb` | +| Apache AGE | LPG | `semantica.graph_store.AgeGraphStore` | built-in | `docs/graph_stores/apache_age.md` | +| RDF4J | RDF | `semantica.triplet_store.RDF4JStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | +| Apache Jena | RDF | `semantica.triplet_store.JenaStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | +| Blazegraph | RDF | `semantica.triplet_store.BlazegraphStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | +| Anzo | RDF | `semantica.triplet_store.AnzoStore` | interface/BYO | `cookbook/introduction/20_Triplet_Store.ipynb` | + +## Feature matrix + +`Yes` means the capability is expected to work with the adapter and graph model. `Partial` means the capability works with model-specific constraints. `BYO` means the user must supply or validate wiring for the backend. + +| Backend | Model | Ingestion | Context graph construction | Reasoning/analytics | Provenance | Known limitations | +| --- | --- | --- | --- | --- | --- | --- | +| Neo4j | LPG | Yes | Yes | Yes | Partial | Provenance and context metadata are stored as node and edge properties; relationship properties and stable node identifiers are required. | +| Amazon Neptune | LPG | Yes | Yes | Partial | Partial | Use the property-graph endpoint; AWS auth, VPC, and endpoint configuration can affect local tests. Provenance depends on node/edge properties. | +| Apache AGE | LPG | Yes | Yes | Partial | Partial | Runs through PostgreSQL/AGE; Cypher compatibility and property handling can differ from standalone LPG engines. | +| RDF4J | RDF | Yes | Partial | Partial | Partial | Context separation relies on named graphs; triple-level provenance may require reification or graph-level metadata. | +| Apache Jena | RDF | Yes | Partial | Partial | Partial | Named graphs are needed for context separation; backend configuration and transaction behavior matter. | +| Blazegraph | RDF | Yes | Partial | Partial | Partial | Use quads/named graphs for context; IRI stability and graph naming matter for provenance. | +| Anzo | RDF | BYO | BYO | BYO | BYO | Anzo deployments are environment-specific; validate repository/graph naming, named-graph support, and provenance mapping. | + +## RDF and LPG differences + +- LPG backends store context and provenance as graph elements and properties. If a backend does not support relationship properties, some provenance patterns may be degraded. +- RDF backends rely on IRIs, named graphs, and optional reification. Context graphs and provenance are easiest to preserve when the store supports named graphs/quads. +- Ingestion works across both models, but the physical representation differs: LPG stores nodes/edges directly, while RDF stores subject-predicate-object statements. +- Reasoning and analytics should be validated against the adapter's query capabilities, especially for path traversal, property filters, and named-graph queries. + +## Minimal connection examples + +Prefer the referenced notebook cells for a working setup. The examples below show the intended adapter entrypoints, not a universal connection DSL. + +### Neo4j + +```python +from semantica.graph_store import Neo4jGraphStore + +store = Neo4jGraphStore( + uri='bolt://localhost:7687', + username='neo4j', + password='password' +) +``` + +### Amazon Neptune + +```python +from semantica.graph_store import NeptuneGraphStore + +store = NeptuneGraphStore( + host='your-neptune-endpoint', + port=8182 +) +``` + +### Apache AGE + +```python +from semantica.graph_store import AgeGraphStore + +store = AgeGraphStore( + dsn='postgresql://user:password@localhost:5432/semantica', + graph='semantica' +) +``` + +### RDF4J + +```python +from semantica.triplet_store import RDF4JStore + +store = RDF4JStore( + url='http://localhost:8080/rdf4j-server', + repository='semantica' +) +``` + +### Apache Jena + +```python +from semantica.triplet_store import JenaStore + +store = JenaStore( + url='http://localhost:3030', + dataset='semantica' +) +``` + +### Blazegraph + +```python +from semantica.triplet_store import BlazegraphStore + +store = BlazegraphStore( + url='http://localhost:9999/blazegraph/sparql' +) +``` + +### Anzo + +```python +from semantica.triplet_store import AnzoStore + +store = AnzoStore( + url='http://anzo-host:10000', + repository='semantica' +) +``` + +Replace hostnames, ports, repositories, graphs, and credentials with values from your environment. For regulated or self-hosted deployments, keep credentials in environment variables or secret storage rather than source code. From fdafffa980de2d1d0a31b74cc44a8bcfde739982 Mon Sep 17 00:00:00 2001 From: KaifAhmad1 Date: Sun, 23 Aug 2026 17:57:53 +0530 Subject: [PATCH 2/2] fix(docs): correct storage-backends adapter names, kwargs, and inventory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The adapter inventory and connection examples referenced classes that don't exist in semantica.graph_store (Neo4jGraphStore, NeptuneGraphStore, AgeGraphStore) and used constructor kwargs that don't match the actual adapters (username vs user, host vs endpoint, url vs endpoint, etc.), verified against each adapter's real __init__ signature and by constructing every example against the live classes. - Correct class names: Neo4jStore, AmazonNeptuneStore, ApacheAgeStore - Fix kwargs for all seven examples to match actual constructors - Fix ApacheAgeStore's connection_string to libpq keyword=value format instead of a postgresql:// DSN, which the adapter doesn't accept - Reclassify Anzo from interface/BYO to built-in — AnzoStore is a real, exported, tested adapter - Add the two adapters missing from the inventory: FalkorDBStore and OxigraphStore - Replace the literal password='password' example with an env var - Note a real RDF4JStore bug found while verifying the RDF4J example: repository_id is a named constructor parameter but the implementation reads it from **config instead, so it's silently ignored and the store always connects to the "default" repository --- docs/storage-backends.md | 76 +++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/docs/storage-backends.md b/docs/storage-backends.md index 689002fb..bb05e115 100644 --- a/docs/storage-backends.md +++ b/docs/storage-backends.md @@ -15,13 +15,15 @@ This page is intentionally conservative: it distinguishes between an adapter exi | Backend | Model | Adapter | Status | Reference | | --- | --- | --- | --- | --- | -| Neo4j | LPG | `semantica.graph_store.Neo4jGraphStore` | built-in | `cookbook/introduction/09_Graph_Store.ipynb` | -| Amazon Neptune | LPG | `semantica.graph_store.NeptuneGraphStore` | built-in | `cookbook/introduction/21_Amazon_Neptune_Store.ipynb` | -| Apache AGE | LPG | `semantica.graph_store.AgeGraphStore` | built-in | `docs/graph_stores/apache_age.md` | +| Neo4j | LPG | `semantica.graph_store.Neo4jStore` | built-in | `cookbook/introduction/09_Graph_Store.ipynb` | +| FalkorDB | LPG | `semantica.graph_store.FalkorDBStore` | built-in | `docs/reference/graph_store.md` | +| Amazon Neptune | LPG | `semantica.graph_store.AmazonNeptuneStore` | built-in | `cookbook/introduction/21_Amazon_Neptune_Store.ipynb` | +| Apache AGE | LPG | `semantica.graph_store.ApacheAgeStore` | built-in | `docs/graph_stores/apache_age.md` | | RDF4J | RDF | `semantica.triplet_store.RDF4JStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | | Apache Jena | RDF | `semantica.triplet_store.JenaStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | | Blazegraph | RDF | `semantica.triplet_store.BlazegraphStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | -| Anzo | RDF | `semantica.triplet_store.AnzoStore` | interface/BYO | `cookbook/introduction/20_Triplet_Store.ipynb` | +| Anzo | RDF | `semantica.triplet_store.AnzoStore` | built-in | `cookbook/introduction/20_Triplet_Store.ipynb` | +| Oxigraph | RDF | `semantica.triplet_store.OxigraphStore` | built-in | `docs/reference/triplet_store.md` | ## Feature matrix @@ -30,12 +32,14 @@ This page is intentionally conservative: it distinguishes between an adapter exi | Backend | Model | Ingestion | Context graph construction | Reasoning/analytics | Provenance | Known limitations | | --- | --- | --- | --- | --- | --- | --- | | Neo4j | LPG | Yes | Yes | Yes | Partial | Provenance and context metadata are stored as node and edge properties; relationship properties and stable node identifiers are required. | +| FalkorDB | LPG | Yes | Yes | Partial | Partial | Redis-based; provenance depends on node/edge properties, and multi-graph isolation depends on the selected graph name. | | Amazon Neptune | LPG | Yes | Yes | Partial | Partial | Use the property-graph endpoint; AWS auth, VPC, and endpoint configuration can affect local tests. Provenance depends on node/edge properties. | | Apache AGE | LPG | Yes | Yes | Partial | Partial | Runs through PostgreSQL/AGE; Cypher compatibility and property handling can differ from standalone LPG engines. | -| RDF4J | RDF | Yes | Partial | Partial | Partial | Context separation relies on named graphs; triple-level provenance may require reification or graph-level metadata. | +| RDF4J | RDF | Yes | Partial | Partial | Partial | Context separation relies on named graphs; triple-level provenance may require reification or graph-level metadata. `RDF4JStore(repository_id=...)` currently has no effect — the constructor always connects to the `"default"` repository regardless of the value passed; track a fix separately. | | Apache Jena | RDF | Yes | Partial | Partial | Partial | Named graphs are needed for context separation; backend configuration and transaction behavior matter. | | Blazegraph | RDF | Yes | Partial | Partial | Partial | Use quads/named graphs for context; IRI stability and graph naming matter for provenance. | -| Anzo | RDF | BYO | BYO | BYO | BYO | Anzo deployments are environment-specific; validate repository/graph naming, named-graph support, and provenance mapping. | +| Anzo | RDF | Yes | Partial | Partial | Partial | Anzo deployments are environment-specific; validate `dataset_uri`/graphmart naming, named-graph support, and provenance mapping. | +| Oxigraph | RDF | Yes | Partial | Partial | Partial | Embedded, single-process store (in-memory or on-disk); named graphs are supported, but there is no separate server process to scale independently. | ## RDF and LPG differences @@ -51,34 +55,48 @@ Prefer the referenced notebook cells for a working setup. The examples below sho ### Neo4j ```python -from semantica.graph_store import Neo4jGraphStore +import os +from semantica.graph_store import Neo4jStore -store = Neo4jGraphStore( +store = Neo4jStore( uri='bolt://localhost:7687', - username='neo4j', - password='password' + user='neo4j', + password=os.environ['NEO4J_PASSWORD'] +) +``` + +### FalkorDB + +```python +from semantica.graph_store import FalkorDBStore + +store = FalkorDBStore( + host='localhost', + port=6379, + graph_name='semantica' ) ``` ### Amazon Neptune ```python -from semantica.graph_store import NeptuneGraphStore +from semantica.graph_store import AmazonNeptuneStore -store = NeptuneGraphStore( - host='your-neptune-endpoint', - port=8182 +store = AmazonNeptuneStore( + endpoint='your-neptune-cluster-endpoint', + port=8182, + region='us-east-1' ) ``` ### Apache AGE ```python -from semantica.graph_store import AgeGraphStore +from semantica.graph_store import ApacheAgeStore -store = AgeGraphStore( - dsn='postgresql://user:password@localhost:5432/semantica', - graph='semantica' +store = ApacheAgeStore( + connection_string='host=localhost dbname=agedb user=postgres password=postgres', + graph_name='semantica' ) ``` @@ -88,8 +106,8 @@ store = AgeGraphStore( from semantica.triplet_store import RDF4JStore store = RDF4JStore( - url='http://localhost:8080/rdf4j-server', - repository='semantica' + endpoint='http://localhost:8080/rdf4j-server', + repository_id='semantica' # currently has no effect; connects to "default" (see Known limitations) ) ``` @@ -99,8 +117,7 @@ store = RDF4JStore( from semantica.triplet_store import JenaStore store = JenaStore( - url='http://localhost:3030', - dataset='semantica' + endpoint='http://localhost:3030/ds' ) ``` @@ -110,7 +127,7 @@ store = JenaStore( from semantica.triplet_store import BlazegraphStore store = BlazegraphStore( - url='http://localhost:9999/blazegraph/sparql' + endpoint='http://localhost:9999/blazegraph/sparql' ) ``` @@ -120,9 +137,18 @@ store = BlazegraphStore( from semantica.triplet_store import AnzoStore store = AnzoStore( - url='http://anzo-host:10000', - repository='semantica' + endpoint='http://anzo-host:8080', + dataset_uri='http://cambridgesemantics.com/Graphmart/your-graphmart-id' ) ``` +### Oxigraph + +```python +from semantica.triplet_store import OxigraphStore + +# Omit `path` for an in-memory store; pass a directory for on-disk persistence. +store = OxigraphStore(path='./semantica-oxigraph-data') +``` + Replace hostnames, ports, repositories, graphs, and credentials with values from your environment. For regulated or self-hosted deployments, keep credentials in environment variables or secret storage rather than source code.