LlamaIndex vector store, reader, retriever, and KV/Doc/Index/Chat storage backends for CockroachDB
Project description
llama-index-cockroachdb
LlamaIndex integration for CockroachDB's native VECTOR column type and the C-SPANN approximate nearest neighbor index, plus a full set of storage backends (KV, document, index, chat). Ships seven classes:
Vector / retrieval:
CockroachDBVectorStore(llama_index.vector_stores.cockroachdb): drop-inBasePydanticVectorStorebacked by CRDB.CockroachDBReader(llama_index.readers.cockroachdb): load existing CRDB rows as LlamaIndexDocumentobjects.CockroachDBRetriever(llama_index.retrievers.cockroachdb): standalone retriever with C-SPANN beam-size tuning.
Storage backends (new in 0.2.0):
CockroachDBKVStore(llama_index.storage.kvstore.cockroachdb): generic key-value store, sync + async.CockroachDBDocumentStore(llama_index.storage.docstore.cockroachdb): persistDocument/Nodeobjects.CockroachDBIndexStore(llama_index.storage.index_store.cockroachdb): persistIndexStructobjects.CockroachDBChatStore(llama_index.storage.chat_store.cockroachdb): persistChatMessagehistory per session.
Requires CockroachDB v25.2+ and Python 3.10+.
Why not just use the pgvector store?
llama-index-vector-stores-postgres depends on the pgvector extension. CockroachDB ships its own native VECTOR(n) type and the C-SPANN distributed ANN index, so the pgvector store cannot be used as-is against a CRDB cluster: the DDL (CREATE EXTENSION vector, USING hnsw) and the per-session tuning vars (hnsw.ef_search, ivfflat.probes) don't exist there. This package targets CRDB's actual API surface.
| Concern | pgvector store | this package |
|---|---|---|
| Column type | pgvector.sqlalchemy.Vector |
native VECTOR(dim) |
| Index DDL | CREATE INDEX ... USING hnsw (...) WITH (m, ef_construction) |
CREATE VECTOR INDEX ... WITH (min_partition_size, max_partition_size) |
| Search-time knob | SET hnsw.ef_search |
SET vector_search_beam_size |
| Setup prereq | CREATE EXTENSION vector |
SET CLUSTER SETTING feature.vector_index.enabled = true |
| Dialect | postgresql+psycopg2 / +asyncpg |
cockroachdb+psycopg2 / cockroachdb+asyncpg (retry-aware) |
HALFVEC |
yes | not yet |
Hybrid / sparse (tsvector) |
yes | not yet (CRDB has no tsvector equivalent) |
Install
pip install llama-index-cockroachdb
You also need a CRDB v25.2+ cluster with the vector feature enabled once at the cluster level:
SET CLUSTER SETTING feature.vector_index.enabled = true;
The store will attempt to set this on first initialization if enable_feature_setting=True (the default) and the connected user has permission.
Quick start
from llama_index.vector_stores.cockroachdb import CockroachDBVectorStore
from llama_index.core import VectorStoreIndex, StorageContext, Document
store = CockroachDBVectorStore.from_params(
host="localhost",
port=26257,
user="root",
password="",
database="defaultdb",
table_name="my_index",
embed_dim=1536,
distance_metric="cosine", # or "l2", "inner_product"
cspann_kwargs={
"min_partition_size": 16,
"max_partition_size": 128,
},
sslmode="disable", # local dev only
)
index = VectorStoreIndex.from_documents(
[Document(text="...")],
storage_context=StorageContext.from_defaults(vector_store=store),
)
print(index.as_query_engine().query("..."))
See examples/ for seven runnable scripts covering async, MMR, metadata filters, the standalone retriever, and the reader.
Tuning C-SPANN
Two levers, both optional:
- Build-time partitioning: pass
cspann_kwargs={"min_partition_size": ..., "max_partition_size": ...}tofrom_params(). These map directly to theWITHclause onCREATE VECTOR INDEX. - Query-time beam size: pass
vector_search_beam_size=Nto the store constructor (applies to every query) or as a kwarg on individualquery()calls. Higher = better recall, slightly more latency. Issued asSET LOCAL vector_search_beam_sizeper session.
store.query(query, vector_search_beam_size=128)
Reader
from llama_index.readers.cockroachdb import CockroachDBReader
reader = CockroachDBReader.from_params(
host="localhost", port=26257, database="defaultdb", user="root", sslmode="disable",
)
docs = reader.load_data(
table="articles",
text_column="body",
metadata_columns=["id", "author", "tag"],
id_column="id",
)
# or pass a query=... with :named params
Retriever
from llama_index.retrievers.cockroachdb import CockroachDBRetriever
from llama_index.embeddings.openai import OpenAIEmbedding
retriever = CockroachDBRetriever(
vector_store=store,
embed_model=OpenAIEmbedding(model="text-embedding-3-small"),
similarity_top_k=5,
vector_search_beam_size=128,
)
nodes_with_scores = retriever.retrieve("What is C-SPANN?")
Storage backends
Each storage class uses the same cockroachdb+psycopg2 / cockroachdb+asyncpg dialects, so transactions retry automatically on SERIALIZATION_FAILURE.
from llama_index.storage.docstore.cockroachdb import CockroachDBDocumentStore
from llama_index.storage.index_store.cockroachdb import CockroachDBIndexStore
from llama_index.storage.chat_store.cockroachdb import CockroachDBChatStore
from llama_index.core import StorageContext
docstore = CockroachDBDocumentStore.from_params(
host="localhost", port=26257, database="defaultdb",
user="root", password="", sslmode="disable",
table_name="docs",
)
index_store = CockroachDBIndexStore.from_params(
host="localhost", port=26257, database="defaultdb",
user="root", password="", sslmode="disable",
table_name="idx",
)
chat_store = CockroachDBChatStore.from_params(
host="localhost", port=26257, database="defaultdb",
user="root", password="", sslmode="disable",
table_name="chats",
)
storage_context = StorageContext.from_defaults(
docstore=docstore,
index_store=index_store,
vector_store=store,
)
CockroachDBChatStore stores each session's messages as a single JSONB array (CRDB does not support ARRAY(JSON) as a column type). Atomic appends use JSONB concatenation (||).
Supported query modes
| Mode | Supported | Notes |
|---|---|---|
DEFAULT |
yes | Vector ANN through C-SPANN |
MMR |
yes | Client-side rerank, configurable mmr_threshold, mmr_prefetch_factor, mmr_prefetch_k |
HYBRID / SPARSE / TEXT_SEARCH |
no | CRDB has no tsvector yet; raises NotImplementedError |
Supported metadata filter operators
EQ, NE, GT, GTE, LT, LTE, IN, NIN, CONTAINS, TEXT_MATCH, TEXT_MATCH_INSENSITIVE, IS_EMPTY. Filters are AND/OR/NOT nestable via MetadataFilters.
For frequently filtered keys, declare indexed_metadata_keys={("category", "text"), ("year", "int")} on the store to get JSONB-extracted BTREE indices.
Development
uv sync --all-extras
uv run pre-commit install
uv run pytest # spins up a CRDB testcontainer per session
uv run ruff check .
Tests can target an existing cluster instead of a container by exporting CRDB_TEST_URL=postgresql://user:pass@host:port/db?sslmode=disable.
License
Apache 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llama_index_cockroachdb-0.2.0.tar.gz.
File metadata
- Download URL: llama_index_cockroachdb-0.2.0.tar.gz
- Upload date:
- Size: 18.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72f2d99596d138d68d02871ef3e709d72917986c33074274a68d63d3d67a3842
|
|
| MD5 |
ba05aec3bc0d937514c9c0f81f47c853
|
|
| BLAKE2b-256 |
628e1281425d4948d7218ab73b1063e919718ace786657f149e5a1c81da12fc9
|
File details
Details for the file llama_index_cockroachdb-0.2.0-py3-none-any.whl.
File metadata
- Download URL: llama_index_cockroachdb-0.2.0-py3-none-any.whl
- Upload date:
- Size: 26.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3452f00b03b4adc1e24f28496f7a2c2fe8addd74b5853a6c53d7f53f4de2e9d2
|
|
| MD5 |
7fa92efc8f162c80af9b0c19298fb8fc
|
|
| BLAKE2b-256 |
fd92f0a9e6ffe1a20ee7cef48233b411eb7b4e617195030175a5248e3e4c7f3f
|