CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-llamaindex

Data framework for your LLM application

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

vector-indexing.mddocs/

Vector Indexing and Storage

Core indexing functionality for creating searchable representations of documents using vector embeddings in LlamaIndex.TS.

Import

import { VectorStoreIndex, Document } from "llamaindex";
// Or from specific submodules
import { VectorStoreIndex } from "llamaindex/indices";
import { SimpleVectorStore } from "llamaindex/vector-store";

Overview

Vector indexing in LlamaIndex.TS converts documents into searchable vector representations using embedding models. The system supports multi-modal data (text, images, audio), various vector stores, and provides sophisticated similarity search capabilities including hybrid search, MMR (Maximum Marginal Relevance), and advanced filtering for retrieval augmented generation (RAG) applications.

VectorStoreIndex

The primary class for creating and managing vector-based indices.

class VectorStoreIndex extends BaseIndex<IndexDict> {
  static async init(options: VectorIndexOptions): Promise<VectorStoreIndex>;
  
  static async fromDocuments(
    documents: Document[],
    args?: VectorIndexOptions
  ): Promise<VectorStoreIndex>;
  
  static async fromVectorStore(
    vectorStore: BaseVectorStore,
    args?: Omit<VectorIndexOptions, "storageContext">
  ): Promise<VectorStoreIndex>;
  
  asQueryEngine(args?: VectorIndexQueryEngineOptions): RetrieverQueryEngine;
  
  asRetriever(args?: VectorIndexRetrieverOptions): VectorIndexRetriever;
  
  asChatEngine(args?: VectorIndexChatEngineOptions): ContextChatEngine;
  
  async insertNodes(nodes: BaseNode[], options?: { logProgress?: boolean }): Promise<void>;
  async insert(document: Document, args?: InsertArgs): Promise<void>;
  async deleteRefDoc(refDocId: string, deleteFromDocStore?: boolean): Promise<void>;
  async deleteNode(nodeId: string): Promise<void>;
  async update(document: Document): Promise<void>;
  async refresh(documents: Document[], args?: RefreshArgs): Promise<void>;
  
  // Multi-modal vector store support
  vectorStores: VectorStoreByType;
  indexStore: BaseIndexStore;
  embedModel?: BaseEmbedding;
}

interface VectorIndexOptions {
  nodes?: BaseNode[];
  storageContext?: StorageContext;
  embedModel?: BaseEmbedding;
  insertBatchSize?: number;
  showProgress?: boolean;
  storeNodesOverride?: boolean;
}

type VectorStoreByType = {
  [ModalityType.TEXT]?: BaseVectorStore;
  [ModalityType.IMAGE]?: BaseVectorStore;
  [ModalityType.AUDIO]?: BaseVectorStore;
};

Vector Stores

BaseVectorStore Interface

Base interface that all vector stores implement with support for multi-modal data and advanced querying.

abstract class BaseVectorStore<Client = unknown, T = unknown> {
  embedModel: BaseEmbedding;
  abstract storesText: boolean;
  abstract flatMetadata: boolean;
  
  abstract client(): Client;
  abstract add(embeddingResults: BaseNode[]): Promise<string[]>;
  abstract delete(refDocId: string, deleteOptions?: object): Promise<void>;
  abstract query(query: VectorStoreQuery<T>, options?: object): Promise<VectorStoreQueryResult>;
  
  // Optional methods for enhanced functionality
  async persist?(persistPath?: string, fsMap?: FileSystem): Promise<void>;
  static async fromParams?(params: any): Promise<BaseVectorStore>;
}

interface VectorStoreConfig {
  textKey?: string;
  docIdKey?: string;
  embeddingKey?: string;
  metadataKey?: string;
  chunkSize?: number;
  addDataToDocStore?: boolean;
}

SimpleVectorStore

In-memory vector store implementation, good for development and small datasets.

class SimpleVectorStore implements BaseVectorStore {
  constructor(data?: SimpleVectorStoreData);
  
  add(nodes: BaseNode[]): Promise<string[]>;
  delete(refDocId: string): Promise<void>;
  query(query: VectorStoreQuery): Promise<VectorStoreQueryResult>;
  persist(persistPath?: string): Promise<void>;
  
  static fromPersistDir(
    persistDir?: string,
    filename?: string
  ): Promise<SimpleVectorStore>;
  
  getData(): SimpleVectorStoreData;
  setData(data: SimpleVectorStoreData): void;
  
  stores_text: boolean;
  is_embedding_query: boolean;
  flat_metadata: boolean;
}

Vector Store Query and Results

VectorStoreQuery

Query object for vector store operations with support for multiple query modes and multi-modal retrieval.

class VectorStoreQuery<T = unknown> {
  constructor(args: {
    queryEmbedding?: number[];
    similarityTopK?: number;
    docIds?: string[];
    nodeIds?: string[];
    queryStr?: string;
    mode?: VectorStoreQueryMode;
    alpha?: number;
    beta?: number;
    filters?: MetadataFilters;
    mmrThreshold?: number;
    sparseTopK?: number;
    hybridTopK?: number;
    modalityTopK?: Partial<Record<ModalityType, number>>;
    outputFields?: string[];
    embeddingField?: string;
  });
  
  queryEmbedding?: number[];
  similarityTopK: number;
  docIds?: string[];
  nodeIds?: string[];
  queryStr?: string;
  mode: VectorStoreQueryMode;
  alpha?: number; // Weight for dense retrieval in hybrid search
  beta?: number;  // Weight for sparse retrieval in hybrid search
  filters?: MetadataFilters;
  mmrThreshold?: number; // MMR diversity threshold
  sparseTopK?: number;   // Top-K for sparse retrieval
  hybridTopK?: number;   // Top-K for hybrid retrieval
  modalityTopK?: Partial<Record<ModalityType, number>>; // Per-modality top-K
  outputFields?: string[];
  embeddingField?: string;
}

enum VectorStoreQueryMode {
  DEFAULT = "default",
  SPARSE = "sparse",
  HYBRID = "hybrid",
  SEMANTIC_HYBRID = "semantic_hybrid",
  MMR = "mmr", // Maximum Marginal Relevance
  SVM = "svm",
  LOGISTIC_REGRESSION = "logistic_regression",
  LINEAR_REGRESSION = "linear_regression",
}

enum ModalityType {
  TEXT = "text",
  IMAGE = "image", 
  AUDIO = "audio",
}

VectorStoreQueryResult

Result object from vector store queries with enhanced result metadata.

class VectorStoreQueryResult {
  constructor(args: {
    nodes?: BaseNode[];
    similarities?: number[];
    ids?: string[];
    metadata?: Record<string, any>[];
  });
  
  nodes?: BaseNode[];
  similarities?: number[];
  ids?: string[];
  metadata?: Record<string, any>[];
}

Metadata Filtering System

LlamaIndex.TS supports sophisticated metadata filtering with multiple operators and conditional logic.

MetadataFilters

interface MetadataFilters {
  filters: MetadataFilter[];
  condition?: FilterCondition;
}

interface MetadataFilter {
  key: string;
  value: FilterValue;
  operator: FilterOperator;
}

type FilterValue = string | number | boolean | string[] | number[];

enum FilterOperator {
  EQ = "==",
  NE = "!=", 
  GT = ">",
  GTE = ">=",
  LT = "<",
  LTE = "<=",
  IN = "in",
  NIN = "nin",
  TEXT_MATCH = "text_match",
  CONTAINS = "contains",
  IS_EMPTY = "is_empty",
  ANY = "any",
  ALL = "all",
}

enum FilterCondition {
  AND = "and",
  OR = "or",
}

Advanced Filtering Examples

// Complex conditional filtering
const complexFilters: MetadataFilters = {
  filters: [
    { key: "category", value: ["tech", "finance"], operator: FilterOperator.IN },
    { key: "year", value: 2024, operator: FilterOperator.GTE },
    { key: "status", value: "published", operator: FilterOperator.EQ },
  ],
  condition: FilterCondition.AND,
};

// Text matching and containment
const textFilters: MetadataFilters = {
  filters: [
    { key: "title", value: "AI", operator: FilterOperator.TEXT_MATCH },
    { key: "tags", value: "machine-learning", operator: FilterOperator.CONTAINS },
  ],
  condition: FilterCondition.OR,
};

Basic Usage

Creating a Vector Index

import { VectorStoreIndex, Document } from "llamaindex";

// Create documents
const documents = [
  new Document({ text: "LlamaIndex is a data framework for LLM applications." }),
  new Document({ text: "It helps connect custom data sources to large language models." }),
  new Document({ text: "Vector databases enable semantic search over document collections." }),
];

// Create vector index (uses default embedding model from Settings)
const index = await VectorStoreIndex.fromDocuments(documents);

console.log("Index created successfully");

Querying the Index

// Create query engine
const queryEngine = index.asQueryEngine();

// Query the index
const response = await queryEngine.query("What is LlamaIndex?");
console.log("Response:", response.toString());

// Access source nodes
console.log("Sources:", response.sourceNodes?.map(node => node.id_));

Using as Retriever

// Create retriever for more control
const retriever = index.asRetriever({
  similarityTopK: 5, // Return top 5 most similar nodes
});

// Retrieve relevant nodes
const retrievedNodes = await retriever.retrieve("semantic search");

retrievedNodes.forEach((node, i) => {
  console.log(`Node ${i}:`, node.text);
  console.log(`Score:`, node.score);
});

Advanced Usage

Custom Vector Store

import { SimpleVectorStore, StorageContext } from "llamaindex";

// Create custom storage context with specific vector store
const vectorStore = new SimpleVectorStore();
const storageContext = StorageContext.fromDefaults({ vectorStore });

// Create index with custom storage
const index = await VectorStoreIndex.fromDocuments(documents, {
  storageContext,
});

Persistent Vector Store

import { SimpleVectorStore } from "llamaindex/vector-store";

// Save vector store to disk
await vectorStore.persist("./vector_store");

// Load vector store from disk
const loadedVectorStore = await SimpleVectorStore.fromPersistDir("./vector_store");

// Create index from loaded vector store
const loadedIndex = VectorStoreIndex.fromVectorStore(loadedVectorStore);

Custom Embedding Model

import { VectorStoreIndex, OpenAIEmbedding } from "llamaindex";

// Create index with specific embedding model
const customEmbedding = new OpenAIEmbedding({
  model: "text-embedding-3-large",
  dimensions: 1536,
});

const index = await VectorStoreIndex.fromDocuments(documents, {
  embed_model: customEmbedding,
});

Filtering with Metadata

// Add documents with metadata
const documentsWithMeta = [
  new Document({ 
    text: "Financial report for Q1 2024", 
    metadata: { category: "finance", year: 2024, quarter: 1 }
  }),
  new Document({ 
    text: "Technical documentation for API v2", 
    metadata: { category: "tech", version: "v2" }
  }),
  new Document({ 
    text: "Marketing strategy for 2024", 
    metadata: { category: "marketing", year: 2024 }
  }),
];

const index = await VectorStoreIndex.fromDocuments(documentsWithMeta);

// Query with metadata filters
const queryEngine = index.asQueryEngine({
  preFilters: {
    filters: [
      { key: "category", value: "finance", operator: "==" },
      { key: "year", value: 2024, operator: "==" }
    ]
  }
});

const response = await queryEngine.query("What was the revenue?");

Index Management

Adding Documents

// Insert single document
const newDoc = new Document({ text: "New information to add to the index." });
await index.insert(newDoc);

// Insert multiple documents
const moreDocs = [
  new Document({ text: "Document 1" }),
  new Document({ text: "Document 2" }),
];

for (const doc of moreDocs) {
  await index.insert(doc);
}

Updating Documents

// Update existing document (requires same ID)
const updatedDoc = new Document({ 
  text: "Updated content", 
  id_: "existing-doc-id" 
});

await index.update(updatedDoc);

Deleting Documents

// Delete by document ID
await index.deleteDocument("doc-id-to-delete");

// Delete specific nodes
await index.deleteNodes(["node-id-1", "node-id-2"]);

Refreshing Index

// Refresh index with updated documents
const refreshedDocs = [
  new Document({ text: "Updated content 1", id_: "doc-1" }),
  new Document({ text: "Updated content 2", id_: "doc-2" }),
];

await index.refresh(refreshedDocs);

Storage Context

Custom Storage Configuration

import { StorageContext, SimpleDocumentStore, SimpleIndexStore, SimpleVectorStore } from "llamaindex";

// Configure all storage components
const storageContext = StorageContext.fromDefaults({
  docStore: new SimpleDocumentStore(),
  indexStore: new SimpleIndexStore(),
  vectorStore: new SimpleVectorStore(),
});

const index = await VectorStoreIndex.fromDocuments(documents, {
  storageContext,
});

Persistent Storage

// Create index with persistent storage
const persistDir = "./storage";
const storageContext = StorageContext.fromDefaults({
  persistDir,
});

const index = await VectorStoreIndex.fromDocuments(documents, {
  storageContext,
});

// Persist to disk
await storageContext.persist(persistDir);

// Load from disk
const loadedStorageContext = StorageContext.fromDefaults({
  persistDir,
});

Performance Optimization

Batch Processing

// Process large document collections in batches
const batchSize = 100;
const largeDocs = /* large array of documents */;

for (let i = 0; i < largeDocs.length; i += batchSize) {
  const batch = largeDocs.slice(i, i + batchSize);
  
  if (i === 0) {
    // Create index with first batch
    index = await VectorStoreIndex.fromDocuments(batch);
  } else {
    // Add subsequent batches
    for (const doc of batch) {
      await index.insert(doc);
    }
  }
  
  console.log(`Processed ${Math.min(i + batchSize, largeDocs.length)} documents`);
}

Memory Management

import { Settings } from "llamaindex";

// Configure for memory efficiency
Settings.chunkSize = 512;  // Smaller chunks
Settings.chunkOverlap = 10; // Less overlap

// Use streaming for large operations
const queryEngine = index.asQueryEngine();
const stream = await queryEngine.query("query", { stream: true });

for await (const chunk of stream) {
  console.log(chunk.response);
}

Integration Examples

With Custom Retriever

import { BaseRetriever } from "llamaindex";

class CustomRetriever implements BaseRetriever {
  async retrieve(query: string): Promise<NodeWithScore[]> {
    // Custom retrieval logic
    const vectorRetriever = index.asRetriever({ similarityTopK: 3 });
    const nodes = await vectorRetriever.retrieve(query);
    
    // Apply custom scoring or filtering
    return nodes.filter(node => node.score! > 0.7);
  }
}

const customRetriever = new CustomRetriever();
const queryEngine = index.asQueryEngine({ retriever: customRetriever });

With Response Synthesis

import { ResponseSynthesizer } from "llamaindex";

const responseSynthesizer = new ResponseSynthesizer({
  responseMode: "tree_summarize", // Use hierarchical summarization
});

const queryEngine = index.asQueryEngine({
  responseSynthesizer,
});

const response = await queryEngine.query("Complex multi-part question");

Best Practices

Index Configuration

// Configure for your use case
const productionIndex = await VectorStoreIndex.fromDocuments(documents, {
  storageContext: StorageContext.fromDefaults({
    persistDir: "./production_storage", // Persistent storage for production
  }),
  showProgress: true, // Show progress for large datasets
});

// Configure retrieval parameters
const queryEngine = productionIndex.asQueryEngine({
  retriever: productionIndex.asRetriever({
    similarityTopK: 5, // Adjust based on your needs
  }),
});

Error Handling

try {
  const index = await VectorStoreIndex.fromDocuments(documents);
  const response = await index.asQueryEngine().query("test query");
  console.log(response.toString());
} catch (error) {
  console.error("Indexing failed:", error);
  // Handle specific error types
  if (error.message.includes("embedding")) {
    console.error("Check your embedding model configuration");
  }
}

Monitoring and Debugging

import { Settings } from "llamaindex";

// Enable debug mode for detailed logging
Settings.debug = true;

// Monitor index size and performance
console.log("Vector store data:", vectorStore.getData());
console.log("Number of nodes:", vectorStore.getData().embeddingDict.size);

docs

chat-engines.md

document-processing.md

embeddings.md

index.md

llm-integration.md

query-engines.md

response-synthesis.md

settings.md

storage.md

tools.md

vector-indexing.md

tile.json