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

ops/2024/9/25 12:31:35/

1、http请求方式

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

请求方式: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]."

                    }

                }

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
}


http://www.ppmy.cn/ops/115777.html

相关文章

2024 Snap 新款ar眼镜介绍

2024 snap 新款ar眼镜介绍 2024 Snap 新款ar眼镜介绍 助力快速掌握数据集的信息和使用方式。

【算法】算法思想合集

数组分块 将数组分成具有某些特征的段使用双指针算法&#xff08;如果是数组&#xff0c;使用下标充当指针&#xff09;存在信息丢失的问题&#xff0c;可以考虑从后向前进行利用单调性进行定性分析&#xff08;盛最多的水&#xff09; 滑动窗口同向移动的双指针出窗口一般是w…

mfc140u.dll引发的软件故障怎么破?mfc140u.dll文件损坏的解决办法全知道!

当这个重要的 DLL 文件丢失或损坏时&#xff0c;用户可能会收到一个错误消息&#xff0c;提示 “程序无法启动&#xff0c;因为计算机中缺失 mfc140u.dll” 或类似的提示。这种情况不仅令人困扰&#xff0c;而且可以干扰正常的工作流程&#xff0c;尤其是当您依赖特定软件完成日…

Uniapp低版本的安卓不能用解决办法

Uniapp低版本的安卓不能用解决办法 语法例子&#xff1a; 语法 不要使用过于新的语法规则 例子&#xff1a; 1. ${aa} 字符变量替换报错 换成连接&#xff0c; 2.let const 报错&#xff0c;换成 var 声明变量 3.includes() 报错 用indexOf替换 4.&#xff08;&#xff09;&…

【深度学习】聊一聊正则化

在机器学习中&#xff0c;正则化是一种常用的技术&#xff0c;用于控制模型的复杂度&#xff0c;减少过拟合的风险。它通过在损失函数中引入额外的项来对模型的参数进行约束或惩罚&#xff0c;使模型更加简单、平滑或稀疏。我们在实际应用中&#xff0c;经常使用的是L1和L2正则…

《深入解析:水果销售数据库操作与查询技巧》

文章目录 一、数据库结构与数据源插入1.1 创建数据库与表1.2 插入数据 二、基础数据查询2.1 查询客户信息2.2 查询供应商信息 三、查询优化与技巧3.1 使用LIMIT子句 四、高级查询技巧4.1 使用聚合函数4.2 连接查询4.3 使用子查询 五、案例分析5.1 客户订单详情查询 一、数据库结…

git remote

git remote 是 Git 版本控制系统中的一个命令&#xff0c;用于管理远程仓库的信息。远程仓库是指存储在网络上的 Git 仓库&#xff0c;通常用于多人协作开发或备份本地仓库。git remote 命令允许你列出、添加、移除、修改远程仓库的引用&#xff08;即别名&#xff09;&#xf…

云计算Openstack

OpenStack是一个开源的云计算管理平台项目&#xff0c;由美国国家航空航天局&#xff08;NASA&#xff09;和Rackspace公司合作研发并发起&#xff0c;以Apache许可证授权。该项目旨在为公共及私有云的建设与管理提供软件支持&#xff0c;通过一系列相互协作的组件实现云计算服…