# How to Configure Polyglot Graph Storage: RDF vs LPG Backends in Semantica

> Configure polyglot graph storage in Semantica by choosing RDF or LPG backends like Neo4j. Learn how to set up your graph database for optimal performance.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-08-18

---

**Initialize the `GraphStore` class with the `backend` parameter set to `"rdf4j"` or `"jena"` for RDF triple stores, or `"neo4j"` or `"falkordb"` for property-graph (LPG) stores, allowing Semantica to automatically instantiate the appropriate driver while maintaining a unified API across both data models.**

Semantica’s polyglot graph storage system abstracts away underlying data model differences, enabling seamless switching between RDF-style triple stores and Labeled Property Graph (LPG) stores. By configuring the `backend` parameter at initialization time, you direct the framework to instantiate specific drivers for RDF4J, Apache Jena, Neo4j, or FalkorDB without modifying your application logic. This configuration flexibility is handled through the `GraphStoreConfig` class and the façade pattern implemented in the core graph store module.

## Understanding Semantica’s Polyglot Architecture

The polyglot capability centers on the **`GraphStore`** façade class implemented in [`semantica/graph_store/graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py). This class delegates all operations to concrete backend implementations while exposing a single, model-agnostic interface.

Under the hood, **`GraphStoreConfig`** (defined in [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py)) parses configuration dictionaries and validates required connection parameters. The configuration system supports two primary backend categories:

- **RDF backends**: Use SPARQL endpoints for query execution. Concrete implementations include **`RDF4JStore`** ([`semantica/triplet_store/rdf4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/rdf4j_store.py)) and **`JenaStore`** ([`semantica/triplet_store/jena_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/jena_store.py)).
- **LPG backends**: Use native Cypher-compatible APIs. Concrete implementations include **`Neo4jStore`** ([`semantica/triplet_store/neo4j_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/triplet_store/neo4j_store.py)) and FalkorDB drivers.

Both backend types implement identical public methods including `add_triplets()`, `query()`, and `export()`, ensuring your code remains agnostic to the underlying storage model.

## Selecting Your Backend at Initialization

Backend selection occurs at initialization time via the `GraphStore` constructor. The `backend` parameter accepts string identifiers that determine which concrete driver class is instantiated.

### RDF Backend Configuration

To configure an RDF triple store, set `backend` to `"rdf4j"` or `"jena"`. RDF backends require SPARQL endpoint configurations:

```python
from semantica.graph_store import GraphStore

# RDF4J backend configuration

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

# Apache Jena backend configuration

jena_store = GraphStore(
    backend="jena",
    endpoint="http://localhost:3030/dataset",
)

```

These configurations instantiate `RDF4JStore` or `JenaStore` respectively, both of which communicate via SPARQL protocols against your triple store endpoints.

### LPG Backend Configuration

For property-graph storage, specify `"neo4j"` or `"falkordb"` as the backend value. LPG backends require Bolt-compatible connection strings and authentication tuples:

```python
from semantica.graph_store import GraphStore

# Neo4j backend configuration

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

# FalkorDB backend configuration

falkor_store = GraphStore(
    backend="falkordb",
    uri="bolt://localhost:6379",
    auth=("falkor", "password"),
)

```

The `Neo4jStore` class handles Cypher query translation, connection pooling, and transaction management to the Neo4j instance specified in the `uri` parameter.

## Configuration Parameters Deep Dive

The configuration system recognizes two critical keys that control backend selection in [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py):

- **`backend`**: Mandatory string specifying the driver type. Accepted values include `"rdf4j"`, `"jena"` (RDF family), and `"neo4j"`, `"falkordb"` (LPG family).
- **`store_type`**: Optional string (`"rdf"` or `"lpg"`) that explicitly forces the data model when a backend supports both. Currently, most backends are model-specific, making this flag primarily useful for future-proofing configurations against multi-model database support.

The `GraphStoreConfig` class validates these parameters, ensuring that required connection strings, authentication tuples, or repository IDs are present before instantiating the concrete store implementation.

## Working with the Unified API

Once initialized, all backend instances share the same public API regardless of whether they store triples or property graphs. This design allows you to write storage-agnostic application logic:

```python
from typing import List
from semantica.graph_store import GraphStore
from semantica.types import Triplet

def ingest_knowledge(store: GraphStore, triples: List[Triplet]) -> None:
    """Add triplets to any configured backend."""
    store.add_triplets(triples)  # Works identically for RDF and LPG

    
def query_graph(store: GraphStore, query_string: str):
    """Execute queries against RDF (SPARQL) or LPG (Cypher) backends."""
    return store.query(query_string)

```

The `GraphStore` façade automatically routes these calls to the appropriate driver implementation, handling protocol translation internally. According to the semantica-agi/semantica source code, this delegation pattern ensures that method signatures remain consistent even as underlying storage mechanisms differ significantly.

## Exporting Data and Format Compatibility

Semantica’s export system automatically detects the active backend type and selects the appropriate exporter class. The detection logic dispatches to **`RDFExporter`** ([`semantica/export/rdf_exporter.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/export/rdf_exporter.py)) or **`LPGExporter`** ([`semantica/export/lpg_exporter.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/export/lpg_exporter.py)) based on the instantiated store type.

Format availability depends on your backend selection:

- **RDF backends**: Support Turtle, RDF/XML, JSON-LD, and other RDF serializations via `RDFExporter`.
- **LPG backends**: Support GraphML, GEXF, and Neo4j CSV dumps via `LPGExporter`.

If you request an incompatible export format, Semantica raises a **`BackendMismatchError`** to prevent data model corruption. For example, attempting to export Turtle format from a Neo4j store triggers this exception, prompting you to either switch backends or select a compatible format like GraphML.

## Summary

- **Initialize with `backend`**: Set to `"rdf4j"` or `"jena"` for RDF triple stores, or `"neo4j"` and `"falkordb"` for LPG stores.
- **Use `GraphStoreConfig`**: Located in [`semantica/graph_store/config.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/config.py), this class validates connection parameters and maps backend strings to concrete driver classes.
- **Write model-agnostic code**: The `GraphStore` façade in [`semantica/graph_store/graph_store.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/graph_store/graph_store.py) provides unified methods like `add_triplets()` and `query()` across all backends.
- **Handle exports carefully**: Automatic format detection routes to `RDFExporter` or `LPGExporter`, but mismatched formats raise `BackendMismatchError`.
- **Optional `store_type`**: Use this configuration key to explicitly declare the data model when working with backends that support multiple storage paradigms.

## Frequently Asked Questions

### What is the difference between RDF and LPG backends in Semantica?

RDF backends store data as subject-predicate-object triples and communicate via SPARQL endpoints, utilizing concrete classes like `RDF4JStore` and `JenaStore` found in `semantica/triplet_store/`. LPG backends store data as nodes and relationships with properties, using Cypher-compatible APIs through classes like `Neo4jStore`. Semantica abstracts these differences behind the `GraphStore` interface, though query languages and export formats remain specific to each model.

### Can I switch from an RDF backend to an LPG backend without changing my code?

Yes, provided you only use the unified API methods such as `add_triplets()` and `query()`. Since `GraphStore` delegates to concrete implementations while maintaining identical method signatures, changing the `backend` parameter from `"rdf4j"` to `"neo4j"` requires no application code changes. However, you must migrate your actual data and update any backend-specific query strings (converting SPARQL to Cypher).

### What happens if I try to export RDF data from an LPG backend?

Semantica raises a `BackendMismatchError` when you request an export format incompatible with the active backend, such as requesting Turtle serialization from a Neo4j store. To resolve this, either select a format supported by LPG exporters like GraphML or GEXF, or reinitialize the `GraphStore` with an RDF backend to access RDF serialization formats.

### Is there a performance difference between RDF and LPG backends in Semantica?

Performance characteristics depend entirely on the underlying database engine rather than Semantica’s abstraction layer. RDF backends (RDF4J, Jena) optimize for SPARQL query performance and triple-pattern matching, while LPG backends (Neo4j, FalkorDB) optimize for graph traversals and relationship-heavy workloads. The `GraphStore` façade introduces minimal overhead, as it directly delegates operations to native drivers without intermediate translation layers during query execution.