跳到主要内容
兼容性:仅适用于 Node.js。
Redis 是一个快速的开源内存数据存储。作为 Redis Stack 的一部分,RediSearch 是一个模块,它支持向量相似性语义搜索以及许多其他类型的搜索。 本指南提供了 Redis 向量存储的快速入门概述。有关所有 RedisVectorStore 功能和配置的详细文档,请参阅 API 参考

概览

集成详情

设置

要使用 Redis 向量存储,您需要设置一个 Redis 实例并安装 @langchain/redis 集成包。您还可以安装 node-redis 包以使用特定的客户端实例初始化向量存储。 本指南还将使用 OpenAI 嵌入,这需要您安装 @langchain/openai 集成包。如果需要,您还可以使用 其他支持的嵌入模型
npm install @langchain/redis @langchain/core redis @langchain/openai
您可以按照这些说明在本地使用 Docker 设置 Redis 实例。

凭据

设置实例后,设置 REDIS_URL 环境变量
process.env.REDIS_URL = "your-redis-url";
如果您在本指南中使用 OpenAI 嵌入,您还需要设置您的 OpenAI 密钥
process.env.OPENAI_API_KEY = "YOUR_API_KEY";
如果您想获取模型调用的自动化跟踪,您还可以通过取消注释下方来设置您的 LangSmith API 密钥
// process.env.LANGSMITH_TRACING="true"
// process.env.LANGSMITH_API_KEY="your-api-key"

实例化

import { RedisVectorStore } from "@langchain/redis";
import { OpenAIEmbeddings } from "@langchain/openai";

import { createClient } from "redis";

const embeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-small",
});

const client = createClient({
  url: process.env.REDIS_URL ?? "redis://:6379",
});
await client.connect();

const vectorStore = new RedisVectorStore(embeddings, {
  redisClient: client,
  indexName: "langchainjs-testing",
});

管理向量存储

向向量存储添加项目

import type { Document } from "@langchain/core/documents";

const document1: Document = {
  pageContent: "The powerhouse of the cell is the mitochondria",
  metadata: { type: "example" },
};

const document2: Document = {
  pageContent: "Buildings are made out of brick",
  metadata: { type: "example" },
};

const document3: Document = {
  pageContent: "Mitochondria are made out of lipids",
  metadata: { type: "example" },
};

const document4: Document = {
  pageContent: "The 2024 Olympics are in Paris",
  metadata: { type: "example" },
};

const documents = [document1, document2, document3, document4];

await vectorStore.addDocuments(documents);
目前不支持顶级文档 ID,但您可以通过直接向向量存储提供文档 ID 来删除文档。

查询向量存储

一旦您的向量存储被创建并添加了相关文档,您很可能希望在链或代理运行期间查询它。

直接查询

执行简单的相似性搜索可以按如下方式完成
const similaritySearchResults = await vectorStore.similaritySearch(
  "biology",
  2
);

for (const doc of similaritySearchResults) {
  console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);
}
过滤功能当前将查找包含所提供字符串的任何元数据键。 如果您想执行相似性搜索并接收相应的分数,可以运行:
const similaritySearchWithScoreResults =
  await vectorStore.similaritySearchWithScore("biology", 2);

for (const [doc, score] of similaritySearchWithScoreResults) {
  console.log(
    `* [SIM=${score.toFixed(3)}] ${doc.pageContent} [${JSON.stringify(
      doc.metadata
    )}]`
  );
}
* [SIM=0.835] The powerhouse of the cell is the mitochondria [{"type":"example"}]
* [SIM=0.852] Mitochondria are made out of lipids [{"type":"example"}]

通过转换为检索器进行查询

您还可以将向量存储转换为检索器,以便在您的链中更轻松地使用。
const retriever = vectorStore.asRetriever({
  k: 2,
});
await retriever.invoke("biology");
[
  Document {
    pageContent: 'The powerhouse of the cell is the mitochondria',
    metadata: { type: 'example' },
    id: undefined
  },
  Document {
    pageContent: 'Mitochondria are made out of lipids',
    metadata: { type: 'example' },
    id: undefined
  }
]

用于检索增强生成的使用

有关如何将此向量存储用于检索增强生成 (RAG) 的指南,请参阅以下部分

删除文档

您可以通过两种方式从向量存储中删除文档

删除所有文档

您可以使用以下命令删除整个索引及其所有文档
await vectorStore.delete({ deleteAll: true });

按 ID 删除特定文档

您还可以通过提供文档 ID 来删除特定文档。请注意,配置的键前缀将自动添加到您提供的 ID 中
// The key prefix will be automatically added to each ID
await vectorStore.delete({ ids: ["doc1", "doc2", "doc3"] });

关闭连接

完成后请务必关闭客户端连接,以避免资源过度消耗
await client.disconnect();

高级功能

自定义 Schema 和元数据过滤

Redis 向量存储支持元数据字段的自定义模式定义,从而实现更高效的过滤和搜索。此功能允许您为元数据定义特定的字段类型和验证规则。

定义自定义 Schema

您可以在创建向量存储时定义自定义模式,以指定字段类型、验证规则和索引选项
import { RedisVectorStore } from "@langchain/redis";
import { OpenAIEmbeddings } from "@langchain/openai";
import { SchemaFieldTypes } from "redis";
import { createClient } from "redis";

const embeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-small",
});

const client = createClient({
  url: process.env.REDIS_URL ?? "redis://:6379",
});
await client.connect();

// Define custom schema for metadata fields
const customSchema:RedisVectorStoreConfig["customSchema"] = {
  userId: {
    type: SchemaFieldTypes.TEXT,
    required: true,
    SORTABLE: true,
  },
  category: {
    type: SchemaFieldTypes.TAG,
    SORTABLE: true,
    SEPARATOR: ",",
  },
  score: {
    type: SchemaFieldTypes.NUMERIC,
    SORTABLE: true,
  },
  tags: {
    type: SchemaFieldTypes.TAG,
    SEPARATOR: ",",
    CASESENSITIVE: true,
  },
  description: {
    type: SchemaFieldTypes.TEXT,
    NOSTEM: true,
    WEIGHT: 2.0,
  },
};

const vectorStoreWithSchema = new RedisVectorStore(embeddings, {
  redisClient: client,
  indexName: "langchainjs-custom-schema",
  customSchema,
});

Schema 字段类型

自定义模式支持三种主要字段类型
  • TEXT:支持全文搜索的字段,可选词干提取、加权和排序
  • TAG:用于精确匹配的分类字段,支持多个值和自定义分隔符
  • NUMERIC:支持范围查询和排序的数字字段

字段配置选项

每个字段都可以配置各种选项
  • required:字段是否必须存在于元数据中(默认值:false)
  • SORTABLE:在此字段上启用排序(默认值:undefined)
  • SEPARATOR:对于 TAG 字段,指定多个值的分隔符(默认值:”,”)
  • CASESENSITIVE:对于 TAG 字段,启用区分大小写的匹配(Redis 期望 true,而不是布尔值)
  • NOSTEM:对于 TEXT 字段,禁用词干提取(Redis 期望 true,而不是布尔值)
  • WEIGHT:对于 TEXT 字段,指定搜索权重(默认值:1.0)

添加带有 Schema 验证的文档

使用自定义模式时,文档会自动根据定义的模式进行验证
import type { Document } from "@langchain/core/documents";

const documentsWithMetadata: Document[] = [
  {
    pageContent: "Advanced JavaScript techniques for modern web development",
    metadata: {
      userId: "user123",
      category: "programming",
      score: 95,
      tags: ["javascript", "web-development", "frontend"],
      description: "Comprehensive guide to JavaScript best practices",
    },
  },
  {
    pageContent: "Machine learning fundamentals and applications",
    metadata: {
      userId: "user456",
      category: "ai",
      score: 88,
      tags: ["machine-learning", "python", "data-science"],
      description: "Introduction to ML concepts and practical applications",
    },
  },
  {
    pageContent: "Database optimization strategies for high performance",
    metadata: {
      userId: "user789",
      category: "database",
      score: 92,
      tags: ["database", "optimization", "performance"],
      description: "Advanced techniques for database performance tuning",
    },
  },
];

// This will validate each document's metadata against the custom schema
await vectorStoreWithSchema.addDocuments(documentsWithMetadata);

带元数据过滤的高级相似性搜索

自定义模式通过 similaritySearchVectorWithScoreAndMetadata 方法实现强大的元数据过滤功能
// Search with TAG filtering
const tagFilterResults =
  await vectorStoreWithSchema.similaritySearchVectorWithScoreAndMetadata(
    await embeddings.embedQuery("programming tutorial"),
    3,
    {
      category: "programming", // Exact tag match
      tags: ["javascript", "frontend"], // Multiple tag OR search
    }
  );

console.log("Tag filter results:");
for (const [doc, score] of tagFilterResults) {
  console.log(`* [SIM=${score.toFixed(3)}] ${doc.pageContent}`);
  console.log(`  Metadata: ${JSON.stringify(doc.metadata)}`);
}
// Search with NUMERIC range filtering
const numericFilterResults =
  await vectorStoreWithSchema.similaritySearchVectorWithScoreAndMetadata(
    await embeddings.embedQuery("high quality content"),
    5,
    {
      score: { min: 90, max: 100 }, // Score between 90 and 100
      category: ["programming", "ai"], // Multiple categories
    }
  );

console.log("Numeric filter results:");
for (const [doc, score] of numericFilterResults) {
  console.log(`* [SIM=${score.toFixed(3)}] ${doc.pageContent}`);
  console.log(
    `  Score: ${doc.metadata.score}, Category: ${doc.metadata.category}`
  );
}
// Search with TEXT field filtering
const textFilterResults =
  await vectorStoreWithSchema.similaritySearchVectorWithScoreAndMetadata(
    await embeddings.embedQuery("development guide"),
    3,
    {
      description: "comprehensive guide", // Text search in description field
      score: { min: 85 }, // Minimum score of 85
    }
  );

console.log("Text filter results:");
for (const [doc, score] of textFilterResults) {
  console.log(`* [SIM=${score.toFixed(3)}] ${doc.pageContent}`);
  console.log(`  Description: ${doc.metadata.description}`);
}

数字范围查询选项

对于数字字段,您可以指定各种范围查询
// Exact value match
{ score: 95 }

// Range with both min and max
{ score: { min: 80, max: 100 } }

// Only minimum value
{ score: { min: 90 } }

// Only maximum value
{ score: { max: 95 } }

错误处理和验证

自定义模式提供自动验证和有用的错误消息
try {
  // This will fail validation - missing required userId field
  const invalidDoc: Document = {
    pageContent: "Some content without required metadata",
    metadata: {
      category: "test",
      // Missing required userId field
    },
  };

  await vectorStoreWithSchema.addDocuments([invalidDoc]);
} catch (error) {
  console.log("Validation error:", error.message);
  // Output: "Required metadata field 'userId' is missing"
}

try {
  // This will fail validation - wrong type for score field
  const wrongTypeDoc: Document = {
    pageContent: "Content with wrong metadata type",
    metadata: {
      userId: "user123",
      score: "not-a-number", // Should be number, not string
    },
  };

  await vectorStoreWithSchema.addDocuments([wrongTypeDoc]);
} catch (error) {
  console.log("Type validation error:", error.message);
  // Output: "Metadata field 'score' must be a number, got string"
}

性能优势

使用自定义模式提供多项性能优势
  1. 索引元数据字段:单独索引各个元数据字段,实现快速过滤
  2. 类型优化查询:数字和标签字段使用优化的查询结构
  3. 减少数据传输:搜索结果中只返回相关字段
  4. 更好的查询规划:Redis 可以根据字段类型和索引优化查询

向后兼容性

自定义模式功能完全向后兼容。现有没有自定义模式的 Redis 向量存储将继续像以前一样工作。您可以逐步迁移到新索引或重建现有索引时使用自定义模式。

API 参考

有关所有 RedisVectorSearch 功能和配置的详细文档,请参阅 API 参考
以编程方式连接这些文档到 Claude、VSCode 等,通过 MCP 获取实时答案。
© . This site is unofficial and not affiliated with LangChain, Inc.