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

sqlite-vec一个SQLite3高效向量搜索扩展--JDBC环境使用

最近要用SQLite3,之前放出来了SQLiteUtile工具,方便操作。今天发现AIGC方面,RAG知识库需要使用向量数据库,来存储知识信息。一般呢都是用mysql,但无奈的是mysql就是不让用。突然又发现SQLite3有向量库扩展组件,索性直接搞下来。用了一下。还可以。

SQLite3的向量库扩展extension,是个开源项目,名字叫sqlite-vec。目前我用到最新版本是0.1.5,配套使用的JDBC是SQLite3.47.0

使用需要注意的是,根据操作系统的不同,下载不同的Release版本库,一般linux要so的,windows要dll的。另外还要注意,下载64位版本的话,JDK、操作系统都得是配套的64位,否则会出现找不到模块的问题。

windows开发环境中,下载sqlite-vec-0.1.5-loadable-windows-x86_64.tar.gz。解压缩后得到vec0.dll。

在工程路径下创建一个extension文件夹,将vec0.dll放进去,便于程序运行时指定相对路径,访问到dll或者so。

demo代码如下:

package org.superx.demo.sqltools;import org.sqlite.SQLiteConfig;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;/****@title DemoSQLiteVec*@description JDBC环境下SQLite扩展sqlite-vec的使用,向量数据库支持。这个示例工程,只能运行一次。二次运行请把./data/sqlite_vec.db删掉*@author superX*@version 1.0.0*@create 2024/11/20 下午3:51**/
public class DemoSQLiteVec {public static void main(String[] args) {// SQLite 连接字符串,建立一个向量数据库String url = "jdbc:sqlite:.\\data\\sqlite_vec.db";// 创建向量表的SQL语句String createTableSQL = "create virtual table IF NOT EXISTS vec_examples using vec0(sample_embedding float[8])";String insertDataSQL1 = "insert into vec_examples(rowid, sample_embedding) " +"values" +"(1, '[-0.200, 0.250, 0.341, -0.211, 0.645, 0.935, -0.316, -0.924]')," +"(2, '[0.443, -0.501, 0.355, -0.771, 0.707, -0.708, -0.185, 0.362]')," +"(3, '[0.716, -0.927, 0.134, 0.052, -0.669, 0.793, -0.634, -0.162]')," +"(4, '[-0.710, 0.330, 0.656, 0.041, -0.990, 0.726, 0.385, -0.958]')";String selectSQL = "select rowid,distance " +"from vec_examples " +"where sample_embedding match '[0.890, 0.544, 0.825, 0.961, 0.358, 0.0196, 0.521, 0.175]' " +"order by distance limit 2";//数据内容表,只能通过rowid来进行关联String createTableSQL2 = "CREATE TABLE IF NOT EXISTS vec_metadata (rowid INTEGER PRIMARY KEY, describe TEXT, label TEXT)";String insertDataSQL2 = "insert into vec_metadata(rowid, describe, label) " +"values" +"(1,'数据描述1','数据标签1')," +"(2,'数据描述2','数据标签2')," +"(3,'数据描述3','数据标签3')," +"(4,'数据描述4','数据标签4')";//数据内容表,只能通过rowid来进行关联查询。而且要注意,vec_examples的查询必须是独立的子查询,否则总是会报错//[SQLITE_ERROR] SQL error or missing database (A LIMIT or 'k = ?' constraint is required on vec0 knn queries.)String selectSQL2 = "SELECT ve.rowid, ve.sample_embedding, vm.describe, vm.label " +"FROM  (SELECT rowid, sample_embedding, distance " +"     FROM vec_examples " +"     WHERE sample_embedding MATCH '[0.890, 0.544, 0.825, 0.961, 0.358, 0.0196, 0.521, 0.175]' " +"     ORDER BY distance " +"     LIMIT 2) ve " +"JOIN vec_metadata vm ON ve.rowid = vm.rowid ";// 创建sqlite配置对象,启用加载扩展功能SQLiteConfig config = new SQLiteConfig();config.enableLoadExtension(true);// 使用配置初始化数据库连接try (Connection conn = DriverManager.getConnection(url, config.toProperties());Statement stmt = conn.createStatement()) {// 加载sqlite-vec扩展库,注意这里dll只能在windows下使用,如果是linux应该是sostmt.execute("SELECT load_extension('./extension/vec0.dll')");// 建表stmt.execute(createTableSQL);// 插入数据stmt.execute(insertDataSQL1);// 查询数据ResultSet rs = stmt.executeQuery(selectSQL);// 打印结果while (rs.next()) {int id = rs.getInt("rowid");float a = rs.getFloat("distance");System.out.println("Row ID: " + id + " distance: " + a);}//创建关联信息表、插入数据并查询stmt.execute(createTableSQL2);stmt.execute(insertDataSQL2);ResultSet rs2 = stmt.executeQuery(selectSQL2);while (rs2.next()) {int id = rs2.getInt("rowid");String describe = rs2.getString("describe");String label = rs2.getString("label");System.out.println("Row ID: " + id + " describe: " + describe + " label: " + label);}/* CMD打印信息结果:代表成功
Row ID: 2 distance: 2.3868737
Row ID: 1 distance: 2.389785
Row ID: 2 describe: 数据描述2 label: 数据标签2
Row ID: 1 describe: 数据描述1 label: 数据标签1*/} catch (Exception e) {e.printStackTrace();}}
}

sqlite-vec创建的向量表限制还是比较多的,virtual table ,using vec0,里面不能随便增加字段。增加字段会报错。所以虚拟向量表是依靠rowid与其他表关联的。这一点要注意!!!

即一般我们做RAG应用时,会embeding文本成向量,然后把向量、文本成对儿存储,再用向量检索机制来寻找最相似的向量对应的文本。使用sqlite-vec的话,需要最少创建2张表。

1张虚拟向量表,只存储rowid和向量信息。另一张表,存储rowid和文本信息,或其它标签信息。检索时,需要进行双表关联检索才能得到想要的信息。如demo

另外需要注意的是,双表关联的语法也有要求。因为sqlite-vec实现是用KNN进行相似搜索,所以查询虚拟向量表时,必须是单表查询,且必须指定limit记录数。所以,关联操作必须以子查询方式进行关联。其它方式都会报错:
[SQLITE_ERROR] SQL error or missing database (A LIMIT or 'k = ?' constraint is required on vec0 knn queries.)

上面的坑为各位踩过了。demo只能运行一遍,因为第二遍运行insert时会报主键冲突,所以多次运行的话,运行前最好把./data/sqlite_vec.db删掉。

SQLite向量扩展开源项目链接,需要其它系统的链接库,自己下载即可:

GitHub - asg017/sqlite-vec: A vector search SQLite extension that runs anywhere!

http://www.lryc.cn/news/490849.html

相关文章:

  • 10 基于深度学习的目标检测
  • leetcode top100中的30道递归和贪心
  • 非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2
  • shell脚本(完)—脚本互调重定向的学习
  • ant-design-vue中table某一列进行合并
  • 基于Springboot+Vue社区养老服务管理系统(源码+lw+讲解部署+PPT)
  • 大数据调度组件之Apache DolphinScheduler
  • 介绍一下strlwr(arr);(c基础)
  • meterpreter常用命令 上
  • 【kubernetes】kubernetes各组件的调用关系
  • Java-08 深入浅出 MyBatis - 多对多模型 SqlMapConfig 与 Mapper 详细讲解测试
  • Vue.js修饰符
  • 【数据分享】2024年我国省市县三级的住宿服务设施数量(8类住宿设施/Excel/Shp格式)
  • 【含文档】基于.NET的医院医保管理系统(含源码+数据库+lw)
  • c++源码阅读__smart_ptr__正文阅读
  • 图形化界面MySQL(MySQL)(超级详细)
  • 【2024 Optimal Control 16-745】Julia语法
  • Opencv+ROS实现摄像头读取处理画面信息
  • 网络安全,文明上网(2)加强网络安全意识
  • 深度学习实战图像缺陷修复
  • jenkins 2.346.1最后一个支持java8的版本搭建
  • 【数据库原理】创建与维护表,DDL数据定义语言
  • 驾驭Go语言中的不确定性:深入错误处理机制
  • 3D Gaussian Splatting在鱼眼相机中的应用与投影变换
  • 【Unity踩坑】在Mac上安装Cocoapods失败
  • uni-app 认识条件编译,了解多端部署
  • SPA 首屏加载慢的原因及解决方案:结合实际项目的详细讲解
  • vue3+ts el-tabel 搜索组件
  • leetcode 排序算法汇总
  • 【C】错误的变量定义导致sprintf()‌输出错误