惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 慕尘

在浏览器跑 Qwen2.5 使用 WSL 在 Windows 上安装 Linux LangExtract pgvector Goose trafilatura unstructured python里使用Playwright python的jieba MinGW nomic-embed-text 解析非结构化数据 LangChain 的 DocumentLoader 能够使用require但不能使用import ChromaDB nvm-windows 使用js实现文字转语音 pyttsx3 Ollama笔记
向量数据库 Faiss
慕尘 · 2025-03-24 · via 博客园 - 慕尘

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