Vector Stores Guide
Learn how to configure and use vector stores for semantic search in RAG pipelines.
Since: v8.44.0 | Status: Stable | Availability: SDK + CLI
Overview
Vector stores are the backbone of semantic search in RAG (Retrieval-Augmented Generation) systems. They store document embeddings and enable fast similarity search to find relevant content for your queries.
NeuroLink provides:
- Abstract VectorStore Interface - Consistent API for any vector database
- InMemoryVectorStore - Built-in store for development and testing
- Provider-Specific Options - Native support for Pinecone, pgVector, and Chroma
- Metadata Filtering - Rich query syntax for filtering results
- Hybrid Search Integration - Combine vector search with BM25 keyword matching
Quick Start
import { InMemoryVectorStore, createVectorQueryTool } from "@juspay/neurolink";
// Create a vector store
const vectorStore = new InMemoryVectorStore();
// Add documents with embeddings
await vectorStore.upsert("my-index", [
{
id: "doc-1",
vector: [0.1, 0.2, 0.3 /* ... embedding values */],
metadata: { text: "Machine learning fundamentals", topic: "ml" },
},
{
id: "doc-2",
vector: [0.15, 0.25, 0.35 /* ... embedding values */],
metadata: { text: "Deep learning architectures", topic: "dl" },
},
]);
// Query for similar documents
const results = await vectorStore.query({
indexName: "my-index",
queryVector: [0.12, 0.22, 0.32 /* ... query embedding */],
topK: 5,
});
console.log(results);
// [{ id: "doc-1", score: 0.95, text: "...", metadata: {...} }, ...]
Available Vector Stores
InMemoryVectorStore
The built-in InMemoryVectorStore is perfect for development, testing, and small-scale applications.
import { InMemoryVectorStore } from "@juspay/neurolink";
const store = new InMemoryVectorStore();
Features:
- Zero dependencies - works out of the box
- Full metadata filtering support
- Cosine similarity search
- No persistence (data lost on restart)
When to Use:
- Development and testing
- Prototyping RAG pipelines
- Small datasets (< 10,000 vectors)
- CI/CD test environments
Limitations:
- Not suitable for production with large datasets
- No persistence across restarts
- Memory-bound scaling
Production Vector Stores
For production deployments, integrate with dedicated vector databases. NeuroLink's VectorStore interface is designed to work with any vector database.
Pinecone Integration
import { Pinecone } from "@pinecone-database/pinecone";
import type { VectorStore } from "@juspay/neurolink";
class PineconeVectorStore implements VectorStore {
private client: Pinecone;
private index: ReturnType<Pinecone["index"]>;
constructor(apiKey: string, indexName: string) {
this.client = new Pinecone({ apiKey });
this.index = this.client.index(indexName);
}
async query(params: {
indexName: string;
queryVector: number[];
topK?: number;
filter?: Record<string, unknown>;
includeVectors?: boolean;
}) {
const response = await this.index.query({
vector: params.queryVector,
topK: params.topK || 10,
filter: params.filter,
includeMetadata: true,
includeValues: params.includeVectors,
});
return response.matches.map((match) => ({
id: match.id,
score: match.score,
text: match.metadata?.text as string,
metadata: match.metadata,
vector: match.values,
}));
}
}
// Usage
const pineconeStore = new PineconeVectorStore(
process.env.PINECONE_API_KEY!,
"my-index",
);
pgVector Integration
import { Pool } from "pg";
import type { VectorStore } from "@juspay/neurolink";
class PgVectorStore implements VectorStore {
private pool: Pool;
constructor(connectionString: string) {
this.pool = new Pool({ connectionString });
}
async query(params: {
indexName: string;
queryVector: number[];
topK?: number;
filter?: Record<string, unknown>;
}) {
const vectorStr = `[${params.queryVector.join(",")}]`;
// WARNING: Validate indexName against allowlist before use
const safeName = params.indexName.replace(/[^a-zA-Z0-9_]/g, "");
const result = await this.pool.query(
`
SELECT id, text, metadata,
1 - (embedding <=> $1::vector) as score
FROM ${safeName}
ORDER BY embedding <=> $1::vector
LIMIT $2
`,
[vectorStr, params.topK || 10],
);
return result.rows.map((row) => ({
id: row.id,
score: row.score,
text: row.text,
metadata: row.metadata,
}));
}
}
Chroma Integration
import { ChromaClient } from "chromadb";
import type { VectorStore } from "@juspay/neurolink";
class ChromaVectorStore implements VectorStore {
private client: ChromaClient;
constructor(path?: string) {
this.client = new ChromaClient({ path });
}
async query(params: {
indexName: string;
queryVector: number[];
topK?: number;
filter?: Record<string, unknown>;
}) {
const collection = await this.client.getCollection({
name: params.indexName,
});
const results = await collection.query({
queryEmbeddings: [params.queryVector],
nResults: params.topK || 10,
where: params.filter,
});
return (results.ids[0] || []).map((id, i) => ({
id,
score: results.distances?.[0]?.[i]
? 1 - results.distances[0][i]
: undefined,
text: results.documents?.[0]?.[i] || undefined,
metadata: results.metadatas?.[0]?.[i] || undefined,
}));
}
}