当前位置: 首页 > news >正文

【Elasticsearch】-实现图片向量相似检索

1、http请求方式

如果elasticsearch服务设置账号密码,则在请求的header中添加 Basic Auth 认证

1.1、余弦相似

请求方式:Post

请求地址:/index_name/_search

请求body:json格式

{"size": 10, //返回条数"min_score": 0.8,  // 设置最低相似分值"_source": ["file_name", "length", "_es_doc_type"],  // 只返回指定字段"query": {"script_score": {"query": {"match_all": {}},"script": {// _img_vector 为设置的向量索引字段  "source": "cosineSimilarity(params.query_vector, '_img_vector') + 0.0","params": {"query_vector": [-1,1,-0.07559559,-0.007800484,0.11229578,0.064164124,....]}}}}
}

主要参数说明

  • "from": 0, // 起始位置,0表示第一页
  • "size": 10, // 每页返回的记录数
  • "min_score": 0.5,   //最低相似度,最高1
  • "_source": ["image_id", "image_name", "image_vector"],   // 返回指定字段

返回结果如下:

{"took": 3,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 0.9014968,"hits": [{"_index": "vedms","_type": "_doc","_id": "04a40e806be82e87f3c3a2f3877225bd.jpg","_score": 0.9014968,"_source": {"file_name": "04a40e806be82e87f3c3a2f3877225bd.jpg","_es_doc_type": "IMAGE","length": 89690}}]}
}

需要确保传入的query_vector 长度一致性,前面的章节中以设定1024长度。

否则会出现如下错误:

"reason": {

                    "type": "script_exception",

                    "reason": "runtime error",

                    "script_stack": [

                        "org.elasticsearch.xpack.vectors.query.ScoreScriptUtils$DenseVectorFunction.<init>(ScoreScriptUtils.java:74)",

                        "org.elasticsearch.xpack.vectors.query.ScoreScriptUtils$CosineSimilarity.<init>(ScoreScriptUtils.java:172)",

                        "cosineSimilarity(params.query_vector, '_img_vector') + 0.0",

                        "     

                    ],

                    "script": "cosineSimilarity(params.query_vector, '_img_vector') + 0.0",

                    "lang": "painless",

                    "position": {

                        "offset": 38,

                        "start": 0,

                        "end": 58

                    },

                    "caused_by": {

                        "type": "illegal_argument_exception",

                        "reason": "The query vector has a different number of dimensions [1023] than the document vectors [1024]."

                    }

                }

1.2、点积相似

{"size": 10, //返回条数"_source": ["file_name", "length", "_es_doc_type"],  // 只返回指定字段"query": {"script_score": {"query": {"match_all": {}},"script": {// _img_vector 为设置的向量索引字段  "source": "dotProduct(params.query_vector, '_img_vector') + 0.0","params": {"query_vector": [-1,1,-0.07559559,-0.007800484,0.11229578,0.064164124,....]}}}}
}

返回结果如下,注意 此时 max_score = 8.157833 ,不再是余弦相似的【0-1】

不在适用使用min_score 参数条件

{"took": 14,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 51,"relation": "eq"},"max_score": 8.157833,"hits": [{"_index": "vedms","_type": "_doc","_id": "04a40e806be82e87f3c3a2f3877225bd.jpg","_score": 8.157833,"_source": {"file_name": "04a40e806be82e87f3c3a2f3877225bd.jpg","_es_doc_type": "IMAGE","length": 89690}},
......

2、Java调用脚本

SearchRequest  不允许在script设置 _source 属性内容,所以干脆将from、size、score一并拿出,只保留vector数据

_img_vector为前面定义的向量索引字段

public List<Map<String, Object>> search(EsVectorSearchReq req) {float[] vector = getImgFeature(req);if (null == vector || vector.length == 0) {return Collections.emptyList();}String queryJson = String.format(VECTOR_FORMAT, vectorToJson(vector));log.debug("向量检索入参条件={}", queryJson);Reader input = new StringReader(queryJson);// 使用查询 DSL 进行搜索SearchRequest searchRequest = new SearchRequest.Builder().index(req.getIndexLib()).from(req.getFrom()).size(req.getSize()).minScore(req.getScore()).source(SourceConfig.of(src -> src.filter(SourceFilter.of(i -> i.includes(req.getColumns()))))).withJson(input).build();// 执行查询List<Map<String, Object>> result = new ArrayList<>();try {SearchResponse<Map> searchResponse = esClient.search(searchRequest, Map.class);// 输出结果for (Hit<Map> hit : searchResponse.hits().hits()) {result.add(hit.source());}log.info("成功查询{}条", result.size());} catch (IOException e) {e.printStackTrace();}return result;}
private String vectorToJson(float[] vector) {StringBuilder sb = new StringBuilder("[");for (int i = 0; i < vector.length; i++) {sb.append(vector[i]);if (i < vector.length - 1) {sb.append(",");}}sb.append("]");return sb.toString();}

private static final String VECTOR_FORMAT = "{\n" +"  \"query\": {\n" +"    \"script_score\": {\n" +"      \"query\": {\n" +"        \"match_all\": {}\n" +"      },\n" +"      \"script\": {\n" +"        \"source\": \"cosineSimilarity(params.query_vector, 'img_vector') + 0.0\",\n" +"        \"params\": {\n" +"          \"query_vector\": %s\n" +"        }\n" +"      }\n" +"    }\n" +"  }\n" +"}";

传入参数格式如下:

{"query": {"script_score": {"query": {"match_all": {}},"script": {"source": "cosineSimilarity(params.query_vector, '_img_vector') + 0.0","params": {"query_vector": [-0.033....]}}}}
}

返回结果如下:

{
    "_shards": {
        "failed": 0.0,
        "skipped": 0.0,
        "successful": 1.0,
        "total": 1.0
    },
    "hits": {
        "hits": [
            {
                "_id": "04a40e806be82e87f3c3a2f3877225bd.jpg",
                "_index": "vedms",
                "_score": 1.0,
                "_source": "{file_name=04a40e806be82e87f3c3a2f3877225bd.jpg}",
                "_type": "_doc"
            }
        ],
        "max_score": 1.0,
        "total": {
            "relation": "eq",
            "value": 1
        }
    },
    "timed_out": false,
    "took": 46
}

相关文章:

  • 科研小白入门工具
  • Android系统:系统架构
  • Mysql 架构
  • GS-SLAM论文阅读笔记--MM3DGS SLAM
  • vue打包后的dist文件如何启动测试
  • 苹果电脑系统重磅更新——macOS Sequoia 15 系统 新功能一 览
  • 2024年软考——信息系统监理师30天冲刺学习指南!!!
  • 2024年自动化、电气控制系统与设备国际学术会议(AECSE 2024)
  • 半导体制造过程中设备通信的高级概述
  • 无人机飞手入伍当兵技术优势分析
  • 【达梦数据库】临时表的使用测试
  • 使用Plotly绘制交互式图表:从入门到精通
  • LabVIEW界面输入值设为默认值
  • 【Python报错已解决】AttributeError: ‘tuple‘ object has no attribute ‘log_softmax‘
  • Voxel mamba :基于Mamba的3D目标检测算法解析
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 【译】理解JavaScript:new 关键字
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • Java Agent 学习笔记
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Linux Process Manage
  • Objective-C 中关联引用的概念
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 构建二叉树进行数值数组的去重及优化
  • 解析带emoji和链接的聊天系统消息
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​业务双活的数据切换思路设计(下)
  • #android不同版本废弃api,新api。
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • $.ajax()
  • (4) PIVOT 和 UPIVOT 的使用
  • (SpringBoot)第二章:Spring创建和使用
  • (笔试题)分解质因式
  • (多级缓存)多级缓存
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)ssm码农论坛 毕业设计 231126
  • (南京观海微电子)——COF介绍
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转载)Linux网络编程入门
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .Net6 Api Swagger配置
  • .NET大文件上传知识整理
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .net项目IIS、VS 附加进程调试
  • @DataRedisTest测试redis从未如此丝滑
  • @Import注解详解
  • [012-1].第12节:Mysql的配置文件的使用
  • [2019.3.5]BZOJ1934 [Shoi2007]Vote 善意的投票