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

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. 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) parses configuration dictionaries and validates required connection parameters. The configuration system supports two primary backend categories:

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:

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:

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:

  • 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:

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) or LPGExporter (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, 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →