The Vector Database System provides an abstraction layer for storing and retrieving document embeddings (vectors) that enable semantic search in AnythingLLM's RAG (Retrieval-Augmented Generation) implementation. This system supports 10+ vector database providers through a common interface, manages workspace-isolated namespaces, implements vector caching for performance optimization, and handles document-to-vector relationships.
For information about how vectors are used during chat execution, see Chat System Architecture. For details on embedding engines that generate the vectors, see Provider Architecture. For text splitting and chunking strategies, see Text Splitting and Chunking.
The vector database system follows a provider abstraction pattern where all database implementations extend the VectorDatabase base class and implement a common interface. Each workspace has an isolated namespace in the vector database, and the system maintains bidirectional mappings between documents and their embedded vectors.
Sources:
All vector database providers extend the VectorDatabase base class and implement a standardized interface. This abstraction allows the application to switch between providers without changing business logic.
| Method | Purpose | Parameters |
|---|---|---|
connect() | Establish connection to vector database | None |
heartbeat() | Check database availability | None |
addDocumentToNamespace() | Embed and store document chunks | namespace, documentData, fullFilePath, skipCache |
deleteDocumentFromNamespace() | Remove document vectors | namespace, docId |
performSimilaritySearch() | Query vectors and retrieve context | namespace, input, LLMConnector, similarityThreshold, topN, filterIdentifiers |
hasNamespace() | Check if namespace exists | namespace |
namespaceCount() | Count vectors in namespace | namespace |
deleteVectorsInNamespace() | Delete entire namespace | client, namespace |
curateSources() | Format search results | sources |
Sources:
The addDocumentToNamespace method implements a multi-stage pipeline that transforms document text into searchable vectors. The pipeline includes caching, text splitting, embedding generation, and batch insertion.
| Parameter | Source | Default | Purpose |
|---|---|---|---|
chunkSize | SystemSettings.text_splitter_chunk_size | 1000 | Maximum characters per chunk |
chunkOverlap | SystemSettings.text_splitter_chunk_overlap | 20 | Character overlap between chunks |
chunkHeaderMeta | TextSplitter.buildHeaderMeta() | null | XML metadata header |
chunkPrefix | EmbedderEngine.embeddingPrefix | "" | Model-specific prefix |
| Batch Size | Provider-specific | 100-500 | Vectors per batch insert |
Sources:
The performSimilaritySearch method executes semantic search queries against the vector database. It embeds the input query, searches for similar vectors, filters results by similarity threshold, and excludes pinned documents.
The system uses cosine similarity with different distance metrics across providers. The distanceToSimilarity method normalizes distances to a 0-1 scale:
LanceDB Distance Conversion (server/utils/vectorDbProviders/lance/index.js39-44):
if distance >= 1.0: return 1
if distance < 0: return 1 - abs(distance)
else: return 1 - distance
Chroma Distance Conversion (server/utils/vectorDbProviders/chroma/index.js112-117):
if distance >= 1.0: return 1
if distance < 0: return 1 - abs(distance)
else: return 1 - distance
LanceDB supports reranking to improve result quality. The reranking process:
NativeEmbeddingReranker to reorder by semantic relevancetopN results after rerankingReranking Configuration (server/utils/vectorDbProviders/lance/index.js119-122):
Sources:
Namespaces provide workspace-level isolation in the vector database. Each workspace has exactly one namespace, and all documents within that workspace are stored in that namespace. Namespace names are often normalized to meet provider-specific requirements.
| Operation | Method | Purpose |
|---|---|---|
| Check Existence | hasNamespace(namespace) | Returns boolean if namespace exists |
| Get Vector Count | namespaceCount(namespace) | Returns number of vectors in namespace |
| Get Statistics | namespace(client, namespace) | Returns namespace metadata and count |
| Delete Namespace | deleteVectorsInNamespace(client, namespace) | Removes entire namespace and all vectors |
| Total Vectors | totalVectors() | Returns sum of vectors across all namespaces |
Different providers have different naming requirements:
Chroma Normalization (server/utils/vectorDbProviders/chroma/index.js31-64):
Milvus/Zilliz Normalization (server/utils/vectorDbProviders/milvus/index.js28-33):
anythingllm_ if invalid first characterWeaviate Normalization (server/utils/vectorDbProviders/weaviate/index.js1-511):
camelCase() transformationAstraDB Normalization (server/utils/vectorDbProviders/astra/index.js10-16):
ns_ prefixSources:
AnythingLLM supports 10+ vector database providers through the common interface. Each provider has specific connection requirements and features.
| Provider | Class | Connection ENV | Special Features |
|---|---|---|---|
| LanceDB | LanceDb | STORAGE_DIR | Local file-based, reranking support |
| Chroma | Chroma | CHROMA_ENDPOINT, CHROMA_API_KEY | Self-hosted, collection normalization |
| Pinecone | PineconeDB | PINECONE_API_KEY, PINECONE_INDEX | Cloud-hosted, serverless |
| Qdrant | QDrant | QDRANT_ENDPOINT, QDRANT_API_KEY | Self/cloud hosted, hybrid search |
| Milvus | Milvus | MILVUS_ADDRESS, MILVUS_USERNAME, MILVUS_PASSWORD | Open-source, high-performance |
| Zilliz | Zilliz | ZILLIZ_ENDPOINT, ZILLIZ_API_TOKEN | Cloud Milvus, extends Milvus class |
| Weaviate | Weaviate | WEAVIATE_ENDPOINT, WEAVIATE_API_KEY | GraphQL API, schema-based |
| AstraDB | AstraDB | ASTRA_DB_APPLICATION_TOKEN, ASTRA_DB_ENDPOINT | Cassandra-based, 20 vectors/batch limit |
LanceDB is the default vector database, requiring no external services. It stores vectors as files in the STORAGE_DIR/lancedb directory.
URI Construction (server/utils/vectorDbProviders/lance/index.js22-27):
Unique Features:
NativeEmbeddingRerankerPinecone (server/utils/vectorDbProviders/pinecone/index.js19-32):
status.readyQdrant (server/utils/vectorDbProviders/qdrant/index.js19-37):
client.api("cluster")?.clusterStatus()AstraDB (server/utils/vectorDbProviders/astra/index.js40-49):
Several providers require vector dimensions during collection creation. The system infers dimensions from the first embedded chunk:
Qdrant (server/utils/vectorDbProviders/qdrant/index.js138-153):
Sources:
The vector cache stores computed embeddings to avoid re-embedding documents that haven't changed. This significantly improves performance when documents are re-indexed or moved between workspaces.
Cache Location: vector-cache/ directory (or STORAGE_DIR/vector-cache/)
Cache Content Format: Each cached file contains an array of chunks, where each chunk is an array of vector objects:
The cache uses the full file path as a unique identifier. The cachedVectorInformation function reads the cache file and returns the stored chunks.
Cache Lookup (server/utils/vectorDbProviders/lance/index.js314-333):
| Scenario | Without Cache | With Cache |
|---|---|---|
| Re-embedding same document | Generate embeddings (slow) | Load from cache (fast) |
| Moving document between workspaces | Generate embeddings | Load from cache |
| API call to embedding provider | Yes (costs money) | No (free) |
| Computation time | ~1-5 seconds per document | ~50-200ms per document |
Sources:
Text splitting breaks documents into manageable chunks before embedding. For detailed documentation on text splitting strategies, see Text Splitting and Chunking.
The TextSplitter class wraps the Langchain RecursiveCharacterTextSplitter and adds metadata injection capabilities.
Constructor Parameters (server/utils/TextSplitter/index.js32-35):
chunkPrefix: Prefix for model-specific requirements (e.g., "passage: ")chunkSize: Maximum characters per chunk (default 1000)chunkOverlap: Character overlap between chunks (default 20)chunkHeaderMeta: Metadata object to inject as XML headerThe system can prepend XML-formatted metadata to each chunk, providing context to the LLM during retrieval:
Header Format (server/utils/TextSplitter/index.js134-147):
Header Building (server/utils/TextSplitter/index.js64-118):
The buildHeaderMeta static method extracts relevant metadata fields:
title → sourceDocumentpublished → publishedchunkSource (if link:// or youtube://) → sourceThe system respects embedding model limits when determining chunk size:
Max Chunk Size Logic (server/utils/TextSplitter/index.js47-57):
Sources:
The DocumentVectors model maintains the relationship between documents and their embedded vectors. This bidirectional mapping enables document deletion, updates, and vector management.
Table: document_vectors
| Column | Type | Purpose |
|---|---|---|
id | Integer | Primary key (auto-increment) |
docId | String | Document identifier (foreign key) |
vectorId | String | UUID of vector in vector database |
Bulk Insert (used during vectorization):
Query by Document (used during deletion):
Delete Mappings (after vector deletion):
Sources:
The system exposes API endpoints for namespace management and statistics. These endpoints are typically accessed by administrators or the frontend UI.
| Endpoint | Method | Purpose |
|---|---|---|
namespace-stats | POST | Get namespace statistics (vector count, metadata) |
delete-namespace | POST | Delete entire namespace and all vectors |
reset | POST | Delete all namespaces (full reset) |
Each provider implements these as async methods with the endpoint name:
namespace-stats Example (server/utils/vectorDbProviders/lance/index.js458-468):
delete-namespace Example (server/utils/vectorDbProviders/lance/index.js470-480):
reset Example (server/utils/vectorDbProviders/lance/index.js482-487):
Sources:
Refresh this wiki