向量数据库 Faiss
Faiss(Facebook AI Similarity Search)是由 Facebook AI Research (FAIR) 开发的高效向量相似性搜索库
npm install faiss-node
使用
import pkg from 'faiss-node'; const { IndexFlatL2, Index, IndexFlatIP, MetricType } = pkg; // 定义向量维度为 2 const dimension = 2; // 创建一个 L2 距离的 Flat 索引 const index = new IndexFlatL2(dimension); // 输出索引的维度、是否训练完成以及当前存储的向量数量 console.log(index.getDimension()); // 2 console.log(index.isTrained()); // true console.log(index.ntotal()); // 0 console.log("========================================") // 向索引中插入数据 index.add([1, 0]); // 插入向量 [1, 0] index.add([1, 2]); // 插入向量 [1, 2] index.add([1, 3]); // 插入向量 [1, 3] index.add([1, 1]); // 插入向量 [1, 1] // 输出当前索引中存储的向量数量 console.log(index.ntotal()); // 4 // 设置查询最近邻的数量 k=4,并执行搜索 const k = 4; const results = index.search([1, 0], k); // 查询与向量 [1, 0] 最近的 4 个向量 console.log("labels:",results.labels); // 输出匹配的向量 ID [ 0, 3, 1, 2 ] //distance = sqrt((x1 - y1)^2 + (x2 - y2)^2 + ... + (xn - yn)^2) console.log("distances:",results.distances); // 输出对应的 L2 距离 [ 0, 1, 4, 9 ] console.log("========================================") // 将索引保存到文件 const fname = 'faiss.index'; index.write(fname); // 保存索引到文件 'faiss.index' // 从文件加载索引 const index_loaded = IndexFlatL2.read(fname); // 从文件读取索引 console.log(index_loaded.getDimension()); // 输出加载索引的维度 2 console.log(index_loaded.ntotal()); // 输出加载索引中存储的向量数量 4 const results1 = index_loaded.search([1, 1], 4); // 查询与向量 [1, 1] 最近的 4 个向量 console.log("labels:",results1.labels); // 输出匹配的向量 ID [ 3, 0, 1, 2 ] console.log("distances:",results1.distances); // 输出对应的 L2 距离 [ 0, 1, 1, 4 ] console.log("========================================") // 创建一个新的 L2 索引并合并现有索引的数据 const newIndex = new IndexFlatL2(dimension); // 创建新的索引 newIndex.mergeFrom(index); // 将现有索引的数据合并到新索引 console.log(newIndex.ntotal()); // 输出新索引中存储的向量数量 4 console.log("========================================") // 删除指定 ID 的向量 console.log(newIndex.search([1, 2], 1)); // 查询与向量 [1, 2] 最近的 1 个向量 const removedCount = newIndex.removeIds([0]); // 删除 ID 为 0 的向量 console.log(removedCount); // 输出删除的向量数量 1 console.log(newIndex.ntotal()); // 输出新索引中剩余的向量数量 3 console.log(newIndex.search([1, 2], 1)); // 再次查询与向量 [1, 2] 最近的 1 个向量 console.log("========================================") // 创建一个内积距离的 Flat 索引 const ipIndex = new IndexFlatIP(2); // 创建内积距离索引 ipIndex.add([1, 0]); // 插入向量 [1, 0] // 将索引序列化为缓冲区并反序列化 const index_buf = newIndex.toBuffer(); // 将索引序列化为缓冲区 const deserializedIndex = Index.fromBuffer(index_buf); // 从缓冲区反序列化索引 console.log(deserializedIndex.ntotal()); // 输出反序列化索引中存储的向量数量 3 console.log("========================================") // 使用工厂方法创建 HNSW 索引,使用内积作为距离度量 const hnswIndex = Index.fromFactory(2, 'HNSW,Flat', MetricType.METRIC_INNER_PRODUCT); // 创建 HNSW 索引 const x = [1, 0, 0, 1]; // 定义训练数据 hnswIndex.train(x); // 训练索引 hnswIndex.add(x); // 插入训练数据 // 定义查询向量 const queryVector = [1, 0]; // 执行搜索,内积公式:dotProduct = sum(x[i] * y[i]),即两个向量对应元素相乘后求和 const searchResults = hnswIndex.search(queryVector, 1); // 输出搜索结果 console.log("labels:", searchResults.labels); // 输出匹配的向量 ID console.log("distances:", searchResults.distances); // 输出对应的内积距离
在LangChain简单示例
安装
npm install @langchain/community @langchain/ollama
应用
import { FaissStore } from "@langchain/community/vectorstores/faiss"; import { OllamaEmbeddings } from "@langchain/ollama"; const embeddings = new OllamaEmbeddings({ baseUrl: "http://XX.XX.XX.XX:11434", // Default value model: "nomic-embed-text:latest", }); // console.log(embeddings) const vectorStore = await FaissStore.fromTexts( ["Hello world", "Bye bye", "hello nice world"], [{ id: 2 }, { id: 1 }, { id: 3 }], embeddings ); const resultOne = await vectorStore.similaritySearch("hello world", 1); console.log(resultOne);
https://github.com/ewfian/faiss-node
https://js.langchain.com.cn/docs/modules/indexes/vector_stores/integrations/faiss