如何基于 Elasticsearch 构建亿级相似图片搜索系统

摘要:在图像识别、以图搜图、图库去重等场景中,传统的关键词搜索已无法满足需求。本文将深入探讨如何利用 Elasticsearch 的向量检索能力,结合深度学习模型,打造高性能的相似图片搜索引擎。


1. 引言:为什么需要"以图搜图"?

想象一下这个场景:用户在电商APP上看到一张喜欢的椅子,但不知道品牌和型号,只需上传图片,系统就能立刻找出同款或风格相似的商品。或者在内容审核平台,需要快速识别并拦截与违规图片"长得像"的变体图片。

传统的基于标签(Keyword)的搜索在这里失效了,因为图片本身是非结构化数据。我们需要的是向量搜索(Vector Search)------将图片转化为计算机能理解的数字指纹(Embeddings),通过计算指纹的相似度来匹配结果。

而 Elasticsearch 不仅仅是全文检索的王者,从 7.x 版本开始,它引入了 dense_vector 字段和 HNSW 算法,使其成为了一个轻量级且强大的向量数据库。

2. 核心原理:图片是如何变成向量的?

要让 ES 搜索图片,首先要解决一个核心问题:如何把图片变成一串数字?

2.1 特征提取(Embedding)

我们需要一个预训练的深度学习模型(CNN、Transformer等),常见的有 ResNet、MobileNet、CLIP 等。

  1. 输入:一张图片(例如 224x224 像素)。
  2. 处理:通过神经网络的卷积层和池化层,提取图片的高层语义特征(颜色分布、纹理、形状、物体轮廓)。
  3. 输出:一个固定长度的浮点数数组(Vector)。例如 ResNet-50 输出的是 1024 维或 2048 维的向量。

通俗理解:这串数字就是图片的"DNA"。两张图片视觉上越像,它们的向量在高维空间中的距离(欧氏距离或余弦相似度)就越近。

2.2 相似度计算

在向量空间中,常用的计算方式有:

  • 余弦相似度(Cosine Similarity):计算两个向量夹角的余弦值,越接近 1 越相似(ES 中最常用)。
  • 欧氏距离(L2 Norm):计算空间中两点的直线距离,越小越相似。
  • 点积(Dot Product):用于特定归一化后的向量。

3. 实战:使用 Elasticsearch 实现图片搜索

接下来,我们分三步走:建表、入库、搜索。

步骤一:定义 Mapping(索引映射)

在 ES 中,我们需要定义一个字段来存储图片向量。假设我们使用 ResNet-50 模型,输出向量维度为 2048。

json 复制代码
PUT /image_index
{
  "mappings": {
    "properties": {
      "image_id": { "type": "keyword" },
      "image_url": { "type": "text" },
      "image_vector": {
        "type": "dense_vector",
        "dims": 2048, 
        "index": true,
        "similarity": "cosine" 
      }
    }
  }
}

关键点

  • type: dense_vector:声明这是一个稠密向量。
  • dims:必须与你使用的 AI 模型输出维度一致。
  • similarity:定义评分算法,这里设为余弦相似度。

步骤二:数据入库(Python 示例)

你需要先用 Python (PyTorch/TensorFlow) 处理图片生成向量,再写入 ES。

python 复制代码
from elasticsearch import Elasticsearch
import numpy as np
from PIL import Image
import torch
# 假设已加载预训练模型 model

es = Elasticsearch("http://localhost:9200")

# 1. 加载图片并预处理
img = Image.open("cat.jpg").resize((224, 224))
img_tensor = preprocess(img) # 转为Tensor并归一化

# 2. 模型推理生成向量
with torch.no_grad():
    vector = model(img_tensor).numpy()[0]
    # ES cosine similarity 要求向量归一化(重要!)
    vector = vector / np.linalg.norm(vector)

# 3. 写入 ES
doc = {
    "image_id": "img_001",
    "image_url": "http://example.com/cat.jpg",
    "image_vector": vector.tolist()
}

es.index(index="image_index", id="1", document=doc)

步骤三:执行相似搜索

当用户上传一张查询图时,流程同样是先生成查询向量 query_vector,然后在 ES 中执行 script_score 查询。

json 复制代码
GET /image_index/_search
{
  "query": {
    "script_score": {
      "query": { "match_all": {} },
      "script": {
        "source": "cosineSimilarity(params.query_vector, 'image_vector') + 1.0",
        "params": {
          "query_vector": [0.12, -0.98, ...] 
        }
      }
    }
  },
  "size": 10
}

注:+ 1.0 是为了避免相似度为负数导致评分小于 0(ES 不支持负分)。

进阶玩法:kNN 搜索(ES 8.x+)

新版本 ES 提供了更高效的 knn 语法,速度更快且更省内存:

json 复制代码
GET /image_index/_knn_search
{
  "knn": {
    "field": "image_vector",
    "query_vector": [0.12, -0.98, ...],
    "k": 10,
    "num_candidates": 100
  },
  "_source": ["image_url"]
}

4. 性能优化:HNSW 算法

如果你的图库有 1000 万张图,全量扫描(Brute Force)是不可接受的。ES 底层使用了 HNSW (Hierarchical Navigable Small World) 图算法。

  • 原理:构建一个多层导航图,搜索时先在高层粗略找,再逐层细化,极大减少计算量。
  • 调优参数
    • m:图的最大连接数,越大索引越准但内存占用越高(默认 16)。
    • ef_construction:构建时的搜索范围,越大索引越慢但质量越好(默认 100)。

5. 优缺点分析

为什么选择 ES 做图片搜索?

  1. 一站式:既能存图片元数据(如上传时间、标签),又能存向量,不需要维护 ES + Milvus/Faiss 两套系统。

  2. 混合搜索 :这是 ES 的杀手锏。你可以实现"找红色的、且款式相似的连衣裙":

    json 复制代码
    "bool": {
      "must": [
        { "match": { "color": "红色" } },
        { "script_score": { ... } } 
      ]
    }
  3. 生态成熟:拥有完善的备份、监控、分片机制。

局限性

  • 相比专业的向量库(如 Milvus),在超大规模(亿级以上)和高并发写入场景下,ES 的资源消耗(尤其是内存)较大,且 HNSW 的图索引构建较慢。

6. 结语

利用 Elasticsearch 实现相似图片搜索,是"深度学习 + 搜索引擎"结合的经典应用。它不需要极其复杂的架构,就能在百万级、千万级数据规模下实现毫秒级的以图搜图。

如果你正在构建图库系统、电商推荐或内容风控平台,不妨试试 ES 的向量能力,让你的图片"活"起来,变得可被检索!


👇 互动话题

你在工作中遇到过哪些非结构化数据搜索的难题?欢迎在评论区留言讨论!

关键词:Elasticsearch, 向量搜索, 以图搜图, 深度学习, ResNet, HNSW

相关推荐
小鸡脚来咯3 小时前
Git 新手入门指南
大数据·git·elasticsearch
说私域6 小时前
基于AI智能名片链动2+1模式服务预约商城系统的社群运营与顾客二次消费吸引策略研究
大数据·人工智能·小程序·开源·流量运营
塔能物联运维10 小时前
隧道照明“智能进化”:PLC 通信 + AI 调光守护夜间通行生命线
大数据·人工智能
highly200910 小时前
Gitflow
大数据·elasticsearch·搜索引擎
humors22111 小时前
韩秀云老师谈买黄金
大数据·程序人生
重生之绝世牛码11 小时前
Linux软件安装 —— SSH免密登录
大数据·linux·运维·ssh·软件安装·免密登录
StarChainTech11 小时前
无人机租赁平台:开启智能租赁新时代
大数据·人工智能·微信小程序·小程序·无人机·软件需求
Hello.Reader11 小时前
Flink DynamoDB Connector 用 Streams 做 CDC,用 BatchWriteItem 高吞吐写回
大数据·python·flink
早日退休!!!11 小时前
内存泄露(Memory Leak)核心原理与工程实践报告
大数据·网络
发哥来了12 小时前
主流AI视频生成工具商用化能力评测:五大关键维度对比分析
大数据·人工智能·音视频