要使用向量嵌入实现分面搜索,需要将基于向量的相似性搜索与基于结构化元数据的传统过滤相结合。首先,为数据集中的每个项目存储向量嵌入(用于语义搜索)和结构化元数据(用于分面)。使用支持混合查询的数据库或搜索引擎,例如 Elasticsearch、带有 pgvector 的 PostgreSQL 或专用的向量数据库(如 Pinecone)。当用户提交查询时,首先使用 Sentence-BERT 或 OpenAI 的嵌入模型将搜索词转换为向量嵌入。然后,执行最近邻向量搜索,同时将分面过滤器(例如,类别、价格范围)应用于元数据。最后,返回按相关性排序的结果,并从过滤后的子集中汇总分面计数。
例如,想象一个用户搜索产品的电商应用。每个产品都有一个转换为向量的描述以及“类别”、“价格”和“品牌”等元数据。查询“防水登山靴”会生成一个向量嵌入,系统会找到相似的产品向量。同时,用户可能会按“价格 < $100”和“品牌:XYZ”进行过滤。数据库检索匹配向量相似性和元数据过滤器的项目。分面计数(例如,剩余项目中多少属于“尺码 10”或“颜色:黑色”)是从过滤结果中计算得出的。Elasticsearch 等工具通过将 k
-最近邻 (kNN) 搜索与用于分面计数的聚合相结合来高效处理此问题,而带有 pgvector 的 PostgreSQL 可能需要在向量结果和元数据表之间进行自定义 SQL 连接。
主要挑战包括平衡性能和准确性。在向量搜索之前按分面进行预过滤可以限制结果,但也可能排除相关项目。后过滤(在向量搜索后应用分面)可确保更好的召回率,但可能需要重新排序。对于大型数据集,近似最近邻 (ANN) 索引(如 FAISS 或 HNSW)可加快向量搜索速度,但需要与元数据过滤集成。从代码角度看,简化的工作流程可能如下所示:
- 使用
all-MiniLM-L6-v2
等模型为所有项目生成嵌入。 - 将向量和元数据存储在混合数据库中。
- 对于查询,嵌入搜索词,运行过滤后的向量搜索,并计算分面。
例如,在 Elasticsearch 中,您可以使用带有 filter
子句和用于分面的 aggregations
的 kNN
查询。在 Python 中,使用 sentence-transformers
和 pgvector
等库,您可以使用 SQL 过滤元数据并手动计算分面。通过缓存常见的分面值或预计算常用过滤器来优化以减少延迟。