1. 从“找相似”说起:为什么我们需要向量检索?
如果你用过电商平台的“找相似”功能,或者音乐App的“推荐相似歌曲”,那你已经体验过向量检索的魅力了。这些功能背后,往往不是简单的关键词匹配,而是将商品、歌曲、文章甚至图片,都转换成一串长长的数字——我们称之为“向量”。这串数字就像一个高维空间里的坐标点,包含了这个物品的深层特征。比如,一件T恤的向量可能包含了“颜色饱和度”、“风格休闲度”、“图案复杂度”等信息。
那么问题来了:当用户点击一件T恤,系统怎么从海量商品里找到风格最接近的那几件呢?答案就是计算这些向量坐标点之间的“距离”或“相似度”。距离越近,或者相似度越高,就认为两件商品越相似。Elasticsearch(后面简称ES)从7.X版本开始,就内置了一个专门处理这种需求的字段类型:dense_vector,中文叫“密集向量”。它能存储最多2048维的浮点数向量,并且直接在查询中计算向量间的相似度,作为搜索结果的排序依据。
听起来有点抽象?别急,你可以把它想象成一个超级升级版的“最近邻”查找。传统数据库找相似,可能靠标签;而向量检索是直接比对特征“指纹”的相似程度,精度和灵活性都高得多。今天,我就来带你深入ES的dense_vector,重点掰扯清楚它提供的四种核心相似度计算方法:cosineSimilarity(余弦相似度)、dotProduct(点积)、l1norm(曼哈顿距离)和l2norm(欧氏距离)。这四种方法就像四把不同的尺子,量出来的“相似”结果可能不一样,适用的场景也各有千秋。搞懂它们,你才能在自己的项目里选出最合适的那把尺子。
2. 实战第一步:创建你的第一个向量索引
理论说再多,不如动手试一下。我们先来搭建一个最简单的实验环境。假设我们要为一个图片库做相似图片搜索,每张图片都被AI模型提取成了一个2维的特征向量(为了演示方便,我们用2维,实际可能高达512或768维)。
首先,我们创建一个名为 image_vector_index 的索引,其中包含一个 dense_vector 类型的字段:
PUT /image_vector_index
{
"settings": {
"number_of_replicas": 0
},
"mappings": {
"properties": {
"image_id": {
"type": "keyword"
},
"feature_vector": {
"type": "dense_vector",
"dims": 2
},
"description": {
"type": "text"
}
}
}
}
这段代码很简单:settings里我们把副本数设为0,方便本地测试;mappings里定义了三个字段。关键就是feature_vector,它的type是dense_vector,并且通过dims: 2指定了向量的维度是2。这里务必注意,维度数dims在创建索引时就必须确定,之后无法修改。所以前期规划好向量模型输出的维度至关重要。
索引建好了,我们来插入一些测试数据。我特意准备了几组有代表性的二维向量,方便你直观感受不同计算方式的差异:
POST /image_vector_index/_bulk
{"index":{}}
{"image_id":"img1", "description":"样例图片1", "feature_vector":[1, 1]}
{"index":{}}
{"image_id":"img2", "description":"样例图片2", "feature_vector":[1, -1]}
{"index":{}}
{"image_id":"img3", "description":"样例图片3", "feature_vector":[1, 0]}
{"index":{}}
{"image_id":"img4", "description":"样例图片4", "feature_vector":[0, 1]}
{"index":{}}
{"image_id":"img5", "description":"样例图片5", "feature_vector":[0, -1]}
{"index":{}}
{"image_id":"img6", "description":"样例图片6", "feature_vector":[-1, 1]}
{"index":{}}
{"image_id":"img7", "description":"样例图片7", "feature_vector":[-1, 0]}
{"index":{}}
{"image_id":"img8", "description":"样例图片8", "feature_vector":[-1, -1]}
这里有一个非常重要的坑我踩过,必须提醒你:绝对不要插入全零向量,比如[0, 0]。 因为在计算余弦相似度时,分母会涉及向量的模长(大小),零向量的模长为0,会导致除法运算报错。在实际业务中,确保你的向量模型不会产出全零向量,或者在前处理阶段进行过滤。
数据准备完毕,我们的舞台已


6638

被折叠的 条评论
为什么被折叠?



