向量数据库:使用Elasticsearch实现向量数据存储与搜索

news/2024/12/29 13:41:20/

向量数据库:使用Elasticsearch实现向量数据存储与搜索

  • 向量数据库:使用Elasticsearch实现向量数据存储与搜索
    • 一、简介
    • 二、实验前准备
      • 2.1 创建索引设置向量字段
      • 2.2 写入数据
    • 三、向量计算函数
      • 3.1 余弦相似度:cosineSimilarity
      • 3.2 计算点积:dotProduct
      • 3.3 曼哈顿距离:l1norm
      • 3.4 欧几里得距离:l2norm
      • 3.5 自定义计算函数

Here’s the table of contents:

向量数据库:使用Elasticsearch实现向量数据存储与搜索

一、简介

  Elasticsearch在7.x的版本中支持 向量检索 。在向量函数的计算过程中,会对所有匹配的文档进行线性扫描。因此,查询预计时间会随着匹配文档的数量线性增长。出于这个原因,建议使用查询参数来限制匹配文档的数量(类似二次查找的逻辑,先使用match query检索到相关文档,然后使用向量函数计算文档相关度)。

  访问dense_vector的推荐方法是通过cosinessimilarity, dotProduct, 1norm或l2norm函数。但是需要注意,每个DSL脚本只能调用这些函数一次。例如,不要在循环中使用这些函数来计算文档向量和多个其他向量之间的相似性。如果需要该功能,可以通过直接访问向量值来重新实现这些函数。

二、实验前准备

2.1 创建索引设置向量字段

  创建一个支持向量检索的mapping,字段类型为dense_vector

// 7.x 支持的 dims 最大为 1024。
PUT index3
{"mappings": {"properties": {"my_vector": {"type": "dense_vector","dims": 3},"my_text" : {"type" : "keyword"}}}
}

2.2 写入数据

PUT index3/_doc/1
{"my_text" : "text1","my_vector" : [0.5, 10, 6]
}PUT index3/_doc/2
{"my_text" : "text2","my_vector" : [-0.5, 10, 10]
}

三、向量计算函数

3.1 余弦相似度:cosineSimilarity

  cosinessimilarity函数计算给定查询向量和文档向量之间的余弦相似性度量。

POST index3/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"source": "cosineSimilarity(params.queryVector, doc['my_vector'])+1.0","params": {"queryVector": [-0.5, 10, 6]}}}}
}
  1. 要限制script_score计算的文档数量,需要提供一个过滤器 (query)。
  2. script脚本在cosineSimilarity上增加了1.0,以防止得分为负。
  3. 为了更好的利用DSL优化器,可以使用参数的方式提供一个查询向量。
  4. 检查缺失值:如果文档中没有用于执行向量函数的向量字段的值,会抛出错误。可以使用doc['my_vector'].size() == 0来检查文档是否有my_vector字段的值。脚本样例:
"source": 
"
doc['my_vector'].size() == 0 ? 0 : 
cosineSimilarity(params.queryVector, 'my_vector')
"

  如果文档的dense_vector字段与查询的向量维度不同,就会抛出异常。

3.2 计算点积:dotProduct

  dotProduct函数计算给定查询向量和文档向量之间的点积度量。

POST index3/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"source": """double value = dotProduct(params.queryVector,doc['my_vector']);return sigmoid(1, Math.E, -value);""","params": {"queryVector": [-0.5,10,6]}}}}
}
  1. 使用标准的sigmoid函数可以防止分数为负。

3.3 曼哈顿距离:l1norm

  l1norm函数计算给定查询向量和文档向量之间的L1距离(曼哈顿距离)。

POST index3/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"source":"1 / (1 + l1norm(params.queryVector, doc['my_vector']))","params": {"queryVector": [-0.5, 10, 6]}}}}
}
  1. 与表示相似性的余弦相似度不同,1norml2norm表示距离或差异。这意味着,向量越相似,由1norml2norm函数产生的分数就越低。因此,当我们需要相似的向量来获得更高的分数时,我们将1norml2norm的输出反过来。另外,为了避免在文档向量与查询完全匹配时被除0,在分母中加了1。

3.4 欧几里得距离:l2norm

  l2norm函数计算给定查询向量和文档向量之间的L2距离(欧几里德距离)。

POST index3/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"source": "1 / (1 + l2norm(params.queryVector, doc['my_vector']))","params": {"queryVector": [-0.5,10,6]}}}}
}

3.5 自定义计算函数

  使用函数访问向量的值,自定义实现向量余弦相似度计算。ES 中向量检索 doc[].vectorValue 函数是在 Elasticsearch 7.8.0 版本开始支持的,在ES 7.5.1 或 7.8.0 以下版本会运行失败。

  可以通过以下函数直接访问向量值:

  • doc[<field>].vectorValue – 以浮点数数组的形式返回向量的值。

  • doc[<field>].magnitude – 将向量的大小作为浮点数返回(对于7.5版本之前创建的向量,其向量的大小不会被存储)。所以这个函数每次被调用时都会进行重新计算。

POST index3/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"source": """float[] v = doc['my_vector'].vectorValue;float vm = doc['my_vector'].magnitude;float dotProduct = 0;for (int i = 0; i < v.length; i++) {dotProduct += v[i] * params.queryVector[i];}return dotProduct / (vm * (float) params.queryVectorMag);""","params": {"queryVector": [-0.5,10,6],"queryVectorMag": 5.25357}}}}
}

http://www.ppmy.cn/news/150927.html

相关文章

js获取html input 单选框值的问题

测试代码&#xff1a; ratio.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"ratio.js"></script> </head> <body><input…

Nginx通过SplitClient进行AB测试以及负载均衡分流

文章目录 前言一、Split Clients是什么&#xff1f;二、使用步骤2.1 根据User-Agent进行分流2.2 根据Cookie进行分流2.3 根据IP地址进行分流2.4 根据时间进行分流2.5 根据随机数进行分流 总结 前言 Nginx是一个被广泛应用的Web服务中间件&#xff0c;今天分享一下如何用它做AB…

继电器带大功率容性负载,启动过程拉弧解决办法

1.选择固态继电器&#xff0c;没有火花了&#xff0c;价格贵。 2.单个200w开关电源&#xff0c;通电瞬间就有40A左右的电流&#xff0c; 建议选择大容量的触点。 3.分时启动&#xff0c;选择不同梯度的延时继电器。我目前用的是这种。 4.并联RC吸收&#xff0c;但是效果不明显。…

600W个微信红包封面,人人都能领取到!!!

过年啦&#xff0c;祝大家春节快乐 牛年大吉&#xff0c;万事如意&#xff01; 别忘了春节还有红包封面领取 新的一年愿大家财运亨通&#xff01; 新年过完了&#xff0c;整理情绪上班了&#xff0c;祝福没有断&#xff0c;问候也依然。努力工作多表现&#xff0c;年后年终奖永…

600W 28KHZ/40KHZ 超声波电路线路板PCB设计

600W 28KHZ/40KHZ 超声波电路线路板PCB采用高精度的运行芯片&#xff0c;在追频率的速度和精度来说得到了很大的提高&#xff0c;特别是水位发生变化或者有清洗篮子的时候能快速找到频率。由于采用了高精度的运行芯片在很多的功能上可以实现&#xff0c;特别是脉冲超声波和加强…

mysql存储过程批量插入数据,构造 15w,150w,600w表

#构造15万(customer表)&#xff0c;150万(orders表)&#xff0c;600万(LINEITEM表)数据差异较大的三张表&#xff0c; #只有数据量最大的表包含主键索引&#xff0c;对上述表进行三表联合查询&#xff0c;对比之前版本查询所耗时间 ##########################################…

天合光能分布式组件如何?600W+分布式大势所趋,引领未来!

7月23日至25日&#xff0c; 2022第十七届中国(济南)国际太阳能利用大会暨中国&#xff08;山东&#xff09;国际新能源产业博览会在济南高新国际会展中心成功举办&#xff0c;天合光能携P型至尊550W——670W系列超高功率组件&#xff0c;N型至尊双面双玻组件以及天合富家原装家…

KDSL-82轻型升流器

一、产品概述 KDSL-82 1000A大电流发生器是一种作为检验用的电流源&#xff0c;大电流试验器采用ARM芯片控制输出工艺和大容量的环形变压器&#xff0c;并且配有液晶屏显示的表计&#xff0c;同时显示一、二次电流、变比和秒表接点(或电位)的动作时间。外配铝合金机箱&#xff…