# Configuring Graph Storage Backends for RDF vs Labeled Property Graphs in Semantica

> Learn to configure graph storage backends for RDF and labeled property graphs in Semantica. Easily switch between storage types with the GraphStore abstraction and a single backend parameter.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: deep-dive
- Published: 2026-09-11

---

**Semantica provides a backend-agnostic `GraphStore` abstraction that enables switching between RDF triple stores and labeled property graphs by setting a single `backend` parameter in `GraphStoreConfig` or passing it directly to the constructor.**

The `semantica-agi/semantica` library decouples graph storage implementation details from high-level operations through a unified interface. When configuring graph storage backends for RDF vs labeled property graphs, you select the appropriate driver via the `backend` argument, and the framework automatically wires the correct manager classes to handle your data.

## The GraphStore Architecture

Semantica's storage layer centers on the **`GraphStore`** class defined in [`semantica/graph_store/graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py). This class acts as a factory that instantiates backend-specific drivers while exposing a consistent high-level API to the rest of the framework.

### Configuration Management

Backend selection begins with **`GraphStoreConfig`**, a dataclass located in [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py). It stores the backend identifier (e.g., `"rdf4j"` or `"neo4j"`) alongside connection parameters such as URIs, credentials, and repository IDs. At runtime, the `GraphStore` constructor consumes this configuration to resolve the backend name to a concrete driver implementation.

### Manager Delegation Pattern

Regardless of the selected backend, `GraphStore` initializes three primary managers that delegate to driver-specific methods:

- **`NodeManager`** – Handles entity creation via `create_node()`
- **`RelationshipManager`** – Manages edge creation between nodes
- **`TripletManager`** – Processes subject-predicate-object statements via `create_triplet()`

These managers call low-level driver methods like `execute_query()`, ensuring your extraction, reasoning, and export pipelines remain storage-agnostic.

## Configuring RDF Triple Store Backends

RDF triple stores excel at semantic-rich knowledge graphs requiring SPARQL queries, OWL inference, or SHACL validation. Semantica supports this paradigm through dedicated drivers in the `semantica/triplet_store/` module.

### Supported RDF Drivers

- **`RDF4JStore`** – Located in [`semantica/triplet_store/rdf4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/rdf4j_store.py), compatible with Eclipse RDF4J servers
- **`JenaStore`** – Located in [`semantica/triplet_store/jena_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/jena_store.py), for Apache Jena deployments

Use the configuration keys `"rdf"` or `"rdf4j"` to select these backends.

### RDF Configuration Example

```python
from semantica.graph_store import GraphStore

# Configure RDF4J backend

rdf_store = GraphStore(
    backend="rdf4j",
    endpoint="http://localhost:9999/rdf4j",
    repository_id="mem"
)

# Create a triple using the triplet manager

rdf_store.triplet_manager.create(
    subject="http://example.org/A",
    predicate="http://example.org/knows",
    obj="http://example.org/B"
)

```

The store exposes SPARQL execution methods through the underlying `RDF4JStore` driver.

## Configuring Labeled Property Graph Backends

Labeled property graphs optimize for high-performance traversals, native property indexing, and graph algorithms using Cypher or Gremlin. Semantica implements these in the `semantica/graph_store/` directory alongside the core abstraction.

### Supported LPG Drivers

- **`Neo4jStore`** – Found in [`semantica/graph_store/neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/neo4j_store.py), uses the Bolt protocol
- **`FalkorDBStore`** – Found in [`semantica/graph_store/falkordb_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/falkordb_store.py), for FalkorDB instances

Configuration keys include `"neo4j"` and `"falkordb"`.

### Neo4j Configuration Example

```python
from semantica.graph_store import GraphStore

# Configure Neo4j backend

neo4j_store = GraphStore(
    backend="neo4j",
    uri="bolt://localhost:7687",
    auth=("neo4j", "secret")
)

# Create a node with labels and properties

neo4j_store.node_manager.create(
    labels=["Person"],
    properties={"name": "Alice"}
)

```

This instantiation wires the `Neo4jStore` driver to handle Cypher-based CRUD operations through the `NodeManager` and `RelationshipManager`.

## Runtime Backend Resolution

When you instantiate `GraphStore`, the constructor performs three steps:

1. Reads the `backend` parameter from arguments or a `GraphStoreConfig` object
2. Resolves the string identifier to a concrete driver class (e.g., `"neo4j"` → `Neo4jStore`)
3. Creates manager instances that delegate to the driver's low-level API

This resolution happens in [`semantica/graph_store/graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py), ensuring that changing storage engines requires modifying only the configuration—not your application logic.

### YAML-Based Configuration

For production deployments, define backends in a YAML file:

```yaml
graph_store:
  backend: neo4j          # Change to "rdf4j" for RDF storage

  uri: bolt://localhost:7687
  auth:
    user: neo4j
    password: secret

```

Load this configuration programmatically:

```python
from semantica.graph_store.config import GraphStoreConfig
from semantica.graph_store import GraphStore

cfg = GraphStoreConfig.from_yaml("config.yaml")
store = GraphStore(**cfg.as_dict())

```

## When to Choose RDF vs Labeled Property Graphs

Select **RDF triple stores** when your workload requires:

- Full RDF semantics with OWL inference or SHACL validation
- SPARQL 1.1 query and update capabilities
- Interoperability with existing semantic web toolchains (Jena, RDF4J)

Select **labeled property graphs** when your workload requires:

- High-performance graph traversals and pathfinding algorithms
- Native indexing of node and edge properties
- Cypher (Neo4j) or Gremlin query languages for complex pattern matching

## Backend-Agnostic Export Capabilities

Semantica's abstraction enables cross-backend workflows. The `RDFExporter` in [`semantica/export/rdf_exporter.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/export/rdf_exporter.py) can serialize data to RDF formats regardless of the underlying storage engine:

```python
from semantica.export.rdf_exporter import RDFExporter

exporter = RDFExporter()
rdf_str = exporter.export_to_rdf(store)  # Works with both RDF and LPG backends

```

This demonstrates how the manager delegation pattern isolates storage specifics while preserving data portability across different graph storage backends.

## Summary

- **Backend-agnostic design**: The `GraphStore` class in [`semantica/graph_store/graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py) abstracts storage implementation behind unified manager interfaces.
- **Configuration-driven**: Use `GraphStoreConfig` in [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py) to select between `"rdf4j"`/`"jena"` (RDF) and `"neo4j"`/`"falkordb"` (LPG) backends.
- **RDF implementations**: Located in `semantica/triplet_store/`, supporting SPARQL and semantic validation.
- **LPG implementations**: Located in `semantica/graph_store/`, optimized for Cypher queries and property indexing.
- **Zero-cost switching**: Change the `backend` parameter to swap storage engines without modifying extraction, reasoning, or export pipelines.

## Frequently Asked Questions

### How do I switch from Neo4j to RDF4J without changing my application code?

Change the `backend` parameter from `"neo4j"` to `"rdf4j"` in your `GraphStore` constructor or configuration file. The `GraphStore` class automatically instantiates `RDF4JStore` instead of `Neo4jStore`, while your calls to `node_manager` and `triplet_manager` remain functionally identical. Ensure your data model aligns with RDF triple semantics (subject-predicate-object) when moving to an RDF backend.

### Can I use SPARQL queries against a Neo4j backend configured in Semantica?

No. SPARQL is specific to RDF triple stores. When configuring a labeled property graph backend like Neo4j, you must use Cypher queries through the driver's `execute_query()` method. However, you can export data from Neo4j to RDF format using `RDFExporter` from [`semantica/export/rdf_exporter.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/export/rdf_exporter.py), then load it into an RDF4J instance to run SPARQL.

### What connection parameters are required for the FalkorDB backend?

The `FalkorDBStore` driver in [`semantica/graph_store/falkordb_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/falkordb_store.py) requires standard Redis connection parameters since FalkorDB runs as a Redis module. Pass `host`, `port`, and optional authentication credentials when constructing `GraphStore` with `backend="falkordb"`. Consult the specific version of FalkorDB you are running for additional configuration options regarding graph persistence and indexing.

### Where does the backend resolution logic live in the source code?

Backend resolution occurs in the `GraphStore` constructor within [`semantica/graph_store/graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py). The class maps the `backend` string (e.g., `"rdf4j"`, `"neo4j"`) to concrete implementations imported from `semantica/triplet_store/` or `semantica/graph_store/` directories, then initializes the appropriate `NodeManager`, `RelationshipManager`, and `TripletManager` instances bound to that driver.