IndraDB

IndraDB is a graph database written in Rust, designed for high performance, safety, and simplicity of implementation. IndraDB offers directed and typed graphs, JSON-based properties tied to vertices and edges, and cross-language support via gRPC.

Key Features

Directed and Typed Graphs

IndraDB supports directed graphs with typed edges and vertices, allowing for detailed and structured relationships within the graph.

JSON-based Properties

Properties in IndraDB are JSON-based, providing a flexible and human-readable way to store additional data on vertices and edges.

Rich Query Semantics

IndraDB enables queries with multiple hops and indexed property queries, offering powerful tools for navigating and manipulating graph data.

Cross-Language Support

IndraDB provides gRPC for cross-language support, with official bindings available for Python and Rust. This makes it easy to integrate IndraDB into applications written in various languages.

Pluggable Datastores

IndraDB features a pluggable datastore architecture, with built-in support for several datastores including PostgreSQL and sled. This allows users to choose the best storage backend for their needs.

High Performance and Safety

Written in Rust, IndraDB benefits from the language's performance and safety features, such as no garbage collection pauses and strong memory safety guarantees.

Usage

IndraDB can be used as a server, a Rust library, or via its CLI. Here are examples for each use case:

Server

The IndraDB server uses gRPC to facilitate cross-language support. Here are some examples:

Python

Python bindings are available and can be installed via PyPI:

import indradb
import uuid
 
client = indradb.Client("localhost:27615")
client.ping()
 
out_v = indradb.Vertex(uuid.uuid4(), "person")
in_v = indradb.Vertex(uuid.uuid4(), "movie")
client.create_vertex(out_v)
client.create_vertex(in_v)
 
edge = indradb.Edge(out_v.id, "bar", in_v.id)
client.create_edge(edge)
 
results = list(client.get(indradb.SpecificEdgeQuery(edge)))
print(results)

Rust

The gRPC bindings library for Rust can be used as follows:

use indradb;
use indradb_proto as proto;
 
let mut client = proto::Client::new("grpc://127.0.0.1:27615".try_into()?).await?;
client.ping().await?;
 
let out_v = indradb::Vertex::new(indradb::Identifier::new("person")?);
let in_v = indradb::Vertex::new(indradb::Identifier::new("movie")?);
client.create_vertex(&out_v).await?;
client.create_vertex(&in_v).await?;
 
let edge = indradb::Edge::new(out_v.id, indradb::Identifier::new("likes")?, in_v.id);
client.create_edge(&edge).await?;
 
let output: Vec<indradb::QueryOutputValue> = client.get(indradb::SpecificEdgeQuery::single(edge.clone())).await?;
let e = indradb::util::extract_edges(output).unwrap();
assert_eq!(e.len(), 1);
assert_eq!(edge, e[0]);

Rust Library

To use IndraDB as a library in Rust:

[dependencies]
indradb-lib = { version = "*", features = ["rocksdb-datastore"] }

Example usage:

use indradb;
 
let db: indradb::Database<indradb::MemoryDatastore> = indradb::MemoryDatastore::new_db();
 
let out_v = indradb::Vertex::new(indradb::Identifier::new("person")?);
let in_v = indradb::Vertex::new(indradb::Identifier::new("movie")?);
db.create_vertex(&out_v)?;
db.create_vertex(&in_v)?;
 
let edge = indradb::Edge::new(out_v.id, indradb::Identifier::new("likes")?, in_v.id);
db.create_edge(&edge)?;
 
let output: Vec<indradb::QueryOutputValue> = db.get(indradb::SpecificEdgeQuery::single(edge.clone()))?;
let e = indradb::util::extract_edges(output).unwrap();
assert_eq!(e.len(), 1);
assert_eq!(edge, e[0]);

CLI

The CLI interacts with a running server. Start the server with indradb-server and use the client to interact:

indradb-client grpc://127.0.0.1:27615 count vertex

Installation

Releases

Pre-compiled releases for Linux and macOS are available:

From Source

To build from source:

  • Install Rust
  • Ensure you have gcc 5+ and the protobuf toolchain installed
  • Clone the repo: git clone git@github.com:indradb/indradb.git
  • Build and install: cargo install

Docker

To run IndraDB in Docker:

Server

Build and run the server:

DOCKER_BUILDKIT=1 docker build --target server -t indradb-server .
docker run --network host --rm indradb-server -a 0.0.0.0:27615

Client

Build and run the client:

DOCKER_BUILDKIT=1 docker build --target client -t indradb-client .
docker run --network host --rm indradb-client grpc://localhost:27615 ping

Datastores

IndraDB supports various datastores with different trade-offs:

Memory

By default, IndraDB uses an in-memory datastore for fast operations with no persistence.

RocksDB

For persistent storage, use the RocksDB datastore:

indradb-server rocksdb [/path/to/rocksdb.rdb] [options]

PostgreSQL and Sled

Other datastores like PostgreSQL and sled are available through separate crates:

Plugins

IndraDB supports plugins for extending functionality. See the hello world plugin and naive vertex plugin for examples.

Testing

Unit Tests

Run the test suite:

make test

You can filter tests with the TEST_NAME environment variable.

Benchmarks

Run microbenchmarks:

make bench

Fuzzing

Run the fuzzer:

make fuzz

Checks

Run lint and formatting checks:

make check

Similar Projects