libs/providers/langchain-redis/README.md
This package contains the LangChain.js integrations for Redis through their SDK.
npm install @langchain/redis @langchain/core
To develop the Redis package, you'll need to follow these instructions:
pnpm install
pnpm build
Or from the repo root:
pnpm build --filter @langchain/redis
Test files should live within a tests/ file in the src/ folder. Unit tests should end in .test.ts and integration tests should
end in .int.test.ts:
$ pnpm test
$ pnpm test:int
Run the linter & formatter to ensure your code is up to standard:
pnpm lint && pnpm format
If you add a new file to be exported, either import & re-export from src/index.ts, or add it to the exports field in the package.json file and run pnpm build to generate the new entrypoint.
The FluentRedisVectorStore is the recommended approach for new projects. It provides a more powerful and type-safe filtering API with support for complex metadata queries. This guide helps you migrate from the legacy RedisVectorStore to FluentRedisVectorStore.
| Feature | RedisVectorStore | FluentRedisVectorStore |
|---|---|---|
| Metadata Schema Definition | Record<string, CustomSchemaField> | MetadataFieldSchema[] |
| Inferred Metadata Schema | No, only custom schema supported | Yes, based on metadata when adding documents |
| Pre-filter - Definition | String arrays or raw query strings | Type-safe FilterExpression objects |
| Pre-filter - Nested conditions | All filters joined by single AND condition | AND, OR, nesting supported |
| Pre-filter - conditions types | Numeric, Tag and Text | Numeric, Tag, Text, Geo, Timestamp |
| Metadata Storage | JSON blob + optional indexed fields | Individual indexed fields (no JSON blob) |
Before (RedisVectorStore):
import { RedisVectorStore } from "@langchain/redis";
After (FluentRedisVectorStore):
import { FluentRedisVectorStore, Tag, Num, Text, Geo } from "@langchain/redis";
The schema format has changed from an object-based to an array-based structure.
Before (RedisVectorStore):
const customSchema = {
userId: { type: SchemaFieldTypes.TAG, required: true },
price: { type: SchemaFieldTypes.NUMERIC, SORTABLE: true },
description: { type: SchemaFieldTypes.TEXT },
location: { type: SchemaFieldTypes.GEO }
};
After (FluentRedisVectorStore):
const customSchema = [
{ name: "userId", type: "tag" },
{ name: "price", type: "numeric", options: { sortable: true } },
{ name: "description", type: "text" },
{ name: "location", type: "geo" }
];
Before:
const vectorStore = await RedisVectorStore.fromDocuments(
documents,
embeddings,
{
redisClient: client,
indexName: "products",
customSchema: {
category: { type: SchemaFieldTypes.TAG },
price: { type: SchemaFieldTypes.NUMERIC, SORTABLE: true }
}
}
);
After:
const vectorStore = await FluentRedisVectorStore.fromDocuments(
documents,
embeddings,
{
redisClient: client,
indexName: "products",
customSchema: [
{ name: "category", type: "tag" },
{ name: "price", type: "numeric", options: { sortable: true } }
]
}
);
The filtering API has changed significantly. Instead of passing metadata objects or string arrays, you now use fluent filter expressions.
Before (RedisVectorStore):
// Simple metadata filtering
const results = await vectorStore.similaritySearchVectorWithScoreAndMetadata(
queryVector,
5,
{ category: "electronics", price: { min: 100, max: 1000 } }
);
// Or with string-based filters
const results = await vectorStore.similaritySearchVectorWithScore(
queryVector,
5,
["electronics", "gadgets"]
);
After (FluentRedisVectorStore):
// Custom filter expression with the fluent API
const results = await vectorStore.similaritySearchVectorWithScore(
queryVector,
5,
Tag("category").eq("electronics").and(Num("price").between(100,1000)
)
);
// Basic filter expression with the fluent API
const results = await vectorStore.similaritySearchVectorWithScore(
queryVector,
5,
Tag("metadata").eq("electronics", "gadgets")
);
The FluentRedisVectorStore only supports metadata stored in individual fields, alongside the vector data and content data.
It is not compatible with the implementation of the RedisVectorStore which stores metadata as a JSON blob in a single field.
The custom schema option of the RedisVectorStore could be migrated to the FluentRedisVectorStore following the instructions in step 2.
To avoid ambiguous results, it's recommended to create a new index with the updated schema and migrate data.
Replace all instances of RedisVectorStore with FluentRedisVectorStore and update filter usage:
Before:
async function searchProducts(query: string, category?: string) {
const results = await vectorStore.similaritySearchVectorWithScoreAndMetadata(
await embeddings.embedQuery(query),
5,
category ? { category } : undefined
);
return results;
}
After:
async function searchProducts(query: string, category?: string) {
const filter = category ? Tag("category").eq(category) : undefined;
const results = await vectorStore.similaritySearchVectorWithScore(
await embeddings.embedQuery(query),
5,
filter
);
return results;
}