当前位置:首页>python>纯PHP也能玩转向量搜索,让你告别Python依赖

纯PHP也能玩转向量搜索,让你告别Python依赖

  • 2026-10-11 08:27:17
纯PHP也能玩转向量搜索,让你告别Python依赖

咱们PHPer做项目时,要是想搞个向量搜索、全文检索,或者混合搜索,之前总免不了要用Python的库,或者依赖外部的向量数据库,不仅技术栈割裂,部署起来也麻烦。

最近发现PHPVector这个纯PHP实现的向量数据库,把HNSW近似最近邻搜索、BM25全文检索都给实现了,还能把两者组合成混合搜索管道,关键是不用啥复杂的外部扩展,PHP8.2+就能跑,简直是为咱们量身定做的。

PHPVector核心能力

简单说,PHPVector 能帮你搞定这几件事:

  • 向量搜索:用 HNSW 算法快速找和查询向量最相似的文档,适合做语义搜索、推荐系统这类场景;
  • 全文搜索:用经典的 BM25 算法根据文本关键词做相关性排序,和传统的全文检索体验一样;
  • 混合搜索:把向量相似度和 BM25 分数融合起来,既能抓语义,又能匹配关键词,搜索结果更准;
  • 轻量持久化:基于文件夹存数据,内存占用低,插入还能异步(装个 ext-pcntl 就行),生产环境用着也放心。

快速上手,5分钟跑通核心流程

话不多说,直接上代码,跟着做一遍就能明白怎么用。

第一步:安装

用 Composer 一键安装:

composer require ezimuel/phpvector

第二步:插入文档

文档里可以放向量、原始文本,还有任意你想随结果返回的元数据,id要是不填,会自动生成UUID v4:

usePHPVector\Document;usePHPVector\VectorDatabase;// 先初始化数据库$db = new VectorDatabase();// 批量插入文档$db->addDocuments([new Document(        id: 1,        vector: [0.12, 0.85, 0.44, 0.67], // 密集嵌入向量        text: 'PHP vector database with HNSW index', // 用于 BM25 的文本        metadata: ['url' => 'https://example.com/1', 'lang' => 'en'], // 自定义元数据    ),new Document(        id: 2,        vector: [0.91, 0.23, 0.78, 0.05],        text: 'Approximate nearest neighbour search in PHP',        metadata: ['url' => 'https://example.com/2', 'lang' => 'en'],    ),new Document(        vector: [0.55, 0.42, 0.71, 0.30], // 不填 id 自动生成 UUID        text: 'Hybrid search with Reciprocal Rank Fusion',    ),]);

第三步:向量搜索

用HNSW找最相似的k个文档,直接返回排名、分数和文档信息:

// 假设这是你的查询向量$queryVector = [0.10, 0.80, 0.50, 0.60];// 找 top 2 相似文档$results = $db->vectorSearch(vector: $queryVector, k: 2);// 遍历输出结果foreach ($results as $result) {echo sprintf("[%d] score=%.4f  %s\n",        $result->rank,        $result->score,        $result->document->metadata['url'] ?? '无链接',    );}// 输出大概长这样:// [1] score=0.9987  https://example.com/1// [2] score=0.8341  https://example.com/3

第四步:全文搜索

用BM25根据文本关键词做相关性排序,和普通全文搜索体验一样:

// 文本查询$results = $db->textSearch(query: 'nearest neighbour PHP', k: 2);foreach ($results as $result) {echo sprintf("[%d] score=%.4f  %s\n",        $result->rank,        $result->score,        $result->document->metadata['url'] ?? '无链接',    );}// 输出:// [1] score=1.2430  https://example.com/2// [2] score=0.8761  https://example.com/1

第五步:混合搜索(推荐)

把向量和文本搜索的结果融合起来,有两种方式:

  • RRF(推荐):基于排名融合,不用调参数,省心
  • 加权组合:自己给向量和文本搜索设权重,更灵活
usePHPVector\HybridMode;// 方式1:RRF 融合(推荐)$results = $db->hybridSearch(    vector: $queryVector,    text: 'vector database PHP',    k: 3,    mode: HybridMode::RRF,);// 方式2:加权组合(比如向量权重 0.7,文本权重 0.3)$results = $db->hybridSearch(    vector: $queryVector,    text: 'vector database PHP',    k: 3,    mode: HybridMode::Weighted,    vectorWeight: 0.7,    textWeight: 0.3,);// 输出结果和前面一样,直接遍历就行

想更精准可以调这些配置

HNSW和 BM25都支持自定义配置,根据你的场景调一调,效果会更好:

usePHPVector\BM25\ConfigasBM25Config;usePHPVector\BM25\SimpleTokenizer;usePHPVector\Distance;usePHPVector\HNSW\ConfigasHNSWConfig;usePHPVector\VectorDatabase;$db = new VectorDatabase(// HNSW 配置    hnswConfig: new HNSWConfig(        M: 16, // 每层节点最大连接数,越高召回越好但内存占得多        efConstruction: 200, // 建索引时的束宽,越高图质量越好但插入慢        efSearch: 50, // 查询时的束宽,越高召回越好但查询慢        distance: Distance::Cosine, // 距离度量:文本嵌入用 Cosine,原始向量用 Euclidean        useHeuristic: true, // 推荐启用,邻居选择更多样化    ),// BM25 配置    bm25Config: new BM25Config(        k1: 1.5, // TF 饱和度,推荐 1.2-2.0        b: 0.75, // 长度归一化,0=不归一,1=完全归一    ),// 分词器配置    tokenizer: new SimpleTokenizer(        stopWords: SimpleTokenizer::DEFAULT_STOP_WORDS, // 停用词        minTokenLength: 2, // 最小分词长度    ),);

这里顺便提下距离度量怎么选:

  • Distance::Cosine:文本嵌入、已归一化向量(最常用)
  • Distance::Euclidean:原始未归一化向量
  • Distance::DotProduct:单位归一化向量(比 Cosine 更快)
  • Distance::Manhattan:稀疏向量,对异常值更鲁棒

生产环境必看:持久化怎么搞

PHPVector用文件夹存数据,每个数据库对应一个目录,里面存HNSW图、BM25索引和单个文档文件,优势是加载时内存占用低(只加载索引,文档懒加载),插入还能异步(装 ext-pcntl 就行)。

保存数据

usePHPVector\Document;usePHPVector\VectorDatabase;// 初始化时指定存储路径$db = new VectorDatabase(path: '/var/data/mydb');// 插入文档(装了 ext-pcntl 会异步写入文档文件)$db->addDocuments([new Document(id: 1, vector: [0.12, 0.85, 0.44], text: 'PHP vector search'),new Document(id: 2, vector: [0.91, 0.23, 0.78], text: 'Approximate nearest neighbour'),]);// 最后调用 save() 把 HNSW 图和 BM25 索引刷盘(会等异步写入完成)$db->save();

加载数据

// 直接 open 已保存的数据库就行$db = VectorDatabase::open('/var/data/mydb');// 接下来直接搜索,和之前一样用$results = $db->vectorSearch(vector: $queryVector, k: 2);

最后

PHPVector最香的地方就是让咱们不用跳出自己的技术栈,就能在项目里加向量搜索、混合搜索这类能力,不管是做个智能搜索、推荐系统,还是知识库问答,都能轻松搞定。

而且它足够轻量不需要外部依赖,部署起来也简单,小项目用它完全够用,大项目也能先拿它做一个原型验证,感兴趣的朋友不妨可以试试!

最新文章

随机文章