vector_store
zocrates.rag.vector_store ¶
Hybrid vector store: Chroma (semantic) + SQLite FTS5 (BM25 keyword).
Architecture¶
- ChromaDB holds embeddings and chunk metadata for semantic (dense) search.
- An auxiliary SQLite database with an FTS5 virtual table holds the raw chunk text for fast full-text (BM25) keyword search.
- Uses FTS5 trigram tokenizer to preserve math expressions (LaTeX) and code.
- Results from both indices are combined with Reciprocal Rank Fusion (RRF) to produce a single ranked list of chunks.
Reranking hook¶
search() accepts an optional reranker callable so a cross-encoder or
other reranker can be plugged in later without changing the call-site.
_FTS_SCHEMA
module-attribute
¶
_FTS_SCHEMA = '\nCREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(\n chunk_id, -- "{item_key}::{chunk_index}"\n item_key,\n chunk_text,\n tokenize = \'trigram\'\n);\n'
_META_SCHEMA
module-attribute
¶
_META_SCHEMA = "\nCREATE TABLE IF NOT EXISTS chunk_meta (\n chunk_id TEXT PRIMARY KEY,\n item_key TEXT NOT NULL,\n item_id INTEGER NOT NULL,\n chunk_index INTEGER NOT NULL,\n chunk_type TEXT NOT NULL DEFAULT 'text',\n heading TEXT,\n parent_item_key TEXT,\n image_path TEXT,\n caption_source TEXT,\n vlm_model TEXT,\n line_start INTEGER,\n line_end INTEGER\n);\n"
ChunkResult
dataclass
¶
ChunkResult(text, heading_path, chunk_index, document_title='', chunk_type='text', image_path=None, caption_source=None, vlm_model=None, line_start=1, line_end=1)
A single text chunk produced from a Markdown document.
EmbedFn ¶
Bases: Protocol
Callable protocol accepted by VectorStore.
SearchResult
dataclass
¶
SearchResult(chunk_text, item_key, item_id, heading_path, chunk_index, score, chunk_type='text', image_path=None, caption_source=None, vlm_model=None, raw_semantic_score=None, raw_keyword_rank=None, retrieval_method='hybrid', title='', creators=None, year=None, chunk_id='', line_start=None, line_end=None)
A single retrieved chunk with provenance information.
VectorStore ¶
Hybrid vector + keyword search index for Zotero document chunks. Uses versioned Chroma collections per embedding model/dimension.
Initialize the VectorStore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chroma_dir
|
Path
|
Directory for ChromaDB persistent storage. |
required |
fts_db_path
|
Path
|
Filesystem path for the SQLite FTS5 database. |
required |
embedder
|
EmbedFn
|
Callable that maps a list of strings to a list of
embedding vectors and exposes |
required |
Source code in zocrates/rag/vector_store.py
acquire_write_lock ¶
Return the store's RLock for external write operations (e.g., model swap).
Returns:
| Type | Description |
|---|---|
Any
|
The |
close ¶
Close the Chroma client and release underlying storage handles.
Source code in zocrates/rag/vector_store.py
delete_document ¶
Remove all chunks for the given item_key from both Chroma and FTS5.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_key
|
str
|
Zotero item key identifying the document to delete. |
required |
get_all_chunk_ids_for_item ¶
Return all chunk IDs for an item key in chunk_index order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_key
|
str
|
Zotero item key. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of chunk IDs. |
Source code in zocrates/rag/vector_store.py
get_all_ingested_item_keys ¶
Return the set of all unique item_key strings currently ingested in the active collection.
Returns:
| Type | Description |
|---|---|
set[str]
|
Set of unique item_key strings. |
Source code in zocrates/rag/vector_store.py
get_all_item_keys ¶
Return the set of all unique item keys indexed in the chunk_meta SQLite table.
Returns:
| Type | Description |
|---|---|
set[str]
|
Set of unique item_key strings. |
Source code in zocrates/rag/vector_store.py
get_intersecting_chunk_ids ¶
Return chunk IDs for an item key that intersect the given line range [start_line, end_line].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_key
|
str
|
Zotero item key. |
required |
start_line
|
int
|
1-indexed start line of the range. |
required |
end_line
|
int
|
1-indexed end line of the range. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of chunk IDs in chunk_index order. |
Source code in zocrates/rag/vector_store.py
ingest_document ¶
Index all chunks from a single document into Chroma and FTS5.
Deletes any existing chunks for item_key before inserting, making
the operation idempotent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_key
|
str
|
Unique Zotero item key used as the primary document ID. |
required |
item_id
|
int
|
Numeric Zotero item ID stored as chunk metadata. |
required |
chunks
|
list[ChunkResult]
|
Ordered list of |
required |
extra_metadata
|
dict[str, Any] | None
|
Additional key/value pairs merged into every chunk's Chroma metadata dict. |
None
|
Source code in zocrates/rag/vector_store.py
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | |
is_ingested ¶
Check whether any chunks exist for item_key in the active collection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_key
|
str
|
Zotero item key to look up. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in zocrates/rag/vector_store.py
list_collections ¶
List all stored versioned Chroma collections with their metadata and chunk counts.
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of dicts, each with keys |
list[dict[str, Any]]
|
|
Source code in zocrates/rag/vector_store.py
reset_collection ¶
Reset/clear vector store collection(s).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
Which collection(s) to reset:
- |
'active'
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dict with keys |
dict[str, Any]
|
|
Source code in zocrates/rag/vector_store.py
963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 | |
search ¶
search(query, top_k=RETRIEVAL_TOP_K, final_k=RETRIEVAL_FINAL_K, item_key_filter=None, chunk_type_filter=None, exclude_chunk_ids=None, reranker=None)
Hybrid (semantic + BM25) search with RRF fusion and raw score metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Natural language query string. |
required |
top_k
|
int
|
Number of candidates retrieved from each index before fusion. |
RETRIEVAL_TOP_K
|
final_k
|
int
|
Maximum number of results to return after fusion. |
RETRIEVAL_FINAL_K
|
item_key_filter
|
list[str] | None
|
If provided, restrict search to these Zotero item keys. |
None
|
chunk_type_filter
|
str | list[str] | None
|
Optional chunk type or list of chunk types to filter by. |
None
|
exclude_chunk_ids
|
set[str] | list[str] | None
|
Optional set or list of chunk IDs to exclude from results. |
None
|
reranker
|
Callable[[str, list[str]], list[float]] | None
|
Optional callable |
None
|
Returns:
| Type | Description |
|---|---|
list[SearchResult]
|
List of |
list[SearchResult]
|
capped at |
Source code in zocrates/rag/vector_store.py
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | |
update_chunk_text_preserve_vector ¶
Update stored document text in Chroma while explicitly preserving existing vector.
Passing existing embeddings explicitly bypasses Chroma's internal embedding function, guaranteeing zero ML overhead, zero network roundtrips, and strict dimension alignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chunk_id
|
str
|
Canonical chunk identifier (e.g. |
required |
new_text
|
str
|
New document text for the chunk. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if chunk was found, had embeddings, and was updated; False otherwise. |
Source code in zocrates/rag/vector_store.py
update_metadata ¶
Update metadata for all chunks belonging to item_key without re-embedding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_key
|
str
|
Zotero item key. |
required |
metadata
|
dict[str, Any]
|
Key/value pairs to merge into existing chunk metadatas. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if chunks were found and updated, False if item was not found. |
Source code in zocrates/rag/vector_store.py
_open_fts_db ¶
Open (or create) the FTS5 and chunk metadata SQLite databases.
Creates the chunks_fts FTS5 virtual table (trigram tokenizer) and
the chunk_meta table if they do not already exist. Migrates missing
columns on chunk_meta if opened on a legacy database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Filesystem path to the SQLite database file. |
required |
Returns:
| Type | Description |
|---|---|
Connection
|
An open |
Connection
|
|
Source code in zocrates/rag/vector_store.py
_rrf_fuse ¶
Combine two ranked lists of chunk IDs using Reciprocal Rank Fusion (RRF).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
semantic_ids
|
list[str]
|
Chunk IDs ordered by descending semantic similarity. |
required |
keyword_ids
|
list[str]
|
Chunk IDs ordered by ascending BM25 rank (rank 1 = best). |
required |
k
|
int
|
RRF smoothing constant (higher reduces the impact of top-ranked items). |
60
|
Returns:
| Type | Description |
|---|---|
list[tuple[str, float]]
|
List of |
Source code in zocrates/rag/vector_store.py
get_collection_name ¶
Generate a sanitized, versioned ChromaDB collection name from model and dimension.
Replaces any non-alphanumeric characters with underscores, collapses consecutive underscores, and appends the dimension suffix.
Example::
get_collection_name("jinaai/jina-embeddings-v5-text-nano", 768)
# -> 'zotero_library_jinaai_jina_embeddings_v5_text_nano_768d'
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Hugging Face or Gemini model identifier. |
required |
dimension
|
int
|
Embedding vector dimension. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A lowercase, underscore-delimited collection name string. |
Source code in zocrates/config.py
get_semantic_similarity_threshold ¶
Return the minimum cosine similarity threshold for semantic vector retrieval.
Reads strictly from semantic_similarity_threshold in zocrates_config.json
(clamped between 0.0 and 1.0, defaulting to 0.50).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Float similarity threshold between 0.0 and 1.0. |