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

news2024/11/25 10:28:26

最近要用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应该是so
            stmt.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.coloradmin.cn/o/2247229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 优先算法 —— 长度最小的子数组(滑动窗口)

目录 题目:长度最小的子数组 1. 题目解析 2. 算法原理 Ⅰ. 暴力枚举 Ⅱ. 滑动窗口(同向双指针) 滑动窗口正确性 3. 代码实现 Ⅰ. 暴力枚举(会超时) Ⅱ. 滑动窗口(同向双指针) 题目:长…

C++设计模式——Singleton单例模式

一、单例模式的定义 单例模式,英文全称Singleton Pattern,是一种创建型设计模式,它保证一个类在程序中仅有一个实例,并对外提供一个访问的该类实例的全局接口。 单例模式通常用于需要控制对象资源的开发场景,一个类…

【Linux系统】—— 基本指令(三)

【Linux系统】—— 基本指令(三) 1 一切皆文件2 重定向操作2.1 初始重定向2.2 重定向的妙用2.3 追加重定向2.4 输入重定向2.5 一切皆文件与重定向结合 3 Linux 中的文件类型4 日志5 「more」命令6 「less」命令7 「head」与「tail」7.1 查看文件开头和结…

探索 Python 任务自动化的新境界:Invoke 库揭秘

文章目录 探索 Python 任务自动化的新境界:Invoke 库揭秘背景:为何选择 Invoke?什么是 Invoke?如何安装 Invoke?5个简单的库函数使用方法1. 定义任务2. 带参数的任务3. 运行 Shell 命令4. 任务参数化5. 列出任务 场景应…

【C++】list模拟实现(详解)

本篇来详细说一下list的模拟实现,list的大体框架实现会比较简单,难的是list的iterator的实现。我们模拟实现的是带哨兵位头结点的list。 1.准备工作 为了不和C库里面的list冲突,我们在实现的时候用命名空间隔开。 //list.h #pragma once #…

shell脚本(6)

声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:shell(6)if条件判断与for循环结构_哔哩哔哩_bilibili 本文主要讲解shell脚本中的if条件判断和for循环结构。 一、if语句 Shell 脚本中的 if 语句…

JavaScript基础 document.write()方法

JavaScript基础 document.write方法 1.简单认识document.write()2.document.write() 的使用 1.简单认识document.write() document.write() 是一种 JavaScript 方法,用于将内容直接写入到 HTML 文档中。它可以用来动态地在页面加载时插入文本、HTML 代码、图片等内…

Linux笔记---进程:进程切换与O(1)调度算法

1. 补充概念 1.1 并行与并发 竞争性:系统进程数目众多,而CPU资源只有少量,甚至只有1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。独立性:多进程运…

使用ENSP实现浮动静态路由

一、项目拓扑 二、项目实现 1.路由器AR1配置 进入系统试图 sys将路由器命名为R1 sysname R1关闭信息中心 undo info-center enable 进入g0/0/0接口 int g0/0/0将g0/0/0接口IP地址配置为1.1.1.1/24 ip address 1.1.1.1 24进入g0/0/1接口 int g0/0/1将g0/0/1接口IP地址配置为2.…

GoF设计模式——结构型设计模式分析与应用

文章目录 UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。1. 继承(抽象,泛化关系)2. 关联3. 组合/聚合各种可能的配合:1. 关联后抽象2. 关联的集合3. 组合接口4. 递归聚合接…

【论文复现】深度知识追踪

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 深度知识追踪 1. 论文概述2. 论文方法3. 实验部分3.1 数据集3.2 实验步骤3.3 实验结果 4 关键代码 1. 论文概述 知识追踪的任务是对学生的知…

Linux: 进程地址空间(理解虚拟地址和页表)

目录 1. 虚拟地址 2. 进程地址空间分布 3. 描述进程地址空间 4. 内存管理——页表 5. 父子进程的虚拟地址关系 6. 页表标记位 6.1 读写权限 6.2 命中权限 7.为什么存在进程地址空间 1. 虚拟地址 #include <stdio.h> #include <unistd.h> #include <sy…

C语言:深入理解指针

一.内存和地址 我们知道计算机上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;需要的数据是在内存中读取的&#xff0c;处理后的数据也会放回内存中&#xff0c;那我们买电脑的时候&#xff0c;电脑上内存是 8GB/16GB/32GB 等&#xff0c;那这些内存空间…

transformer.js(一):这个前端大模型运行框架的可运行环境、使用方式、代码示例以及适合与不适合的场景

随着大模型的广泛应用&#xff0c;越来越多的开发者希望在前端直接运行机器学习模型&#xff0c;从而减少对后端的依赖&#xff0c;并提升用户体验。Transformer.js 是一个专为前端环境设计的框架&#xff0c;它支持运行基于 Transformer 架构的深度学习模型&#xff0c;尤其是…

uni-app 发布媒介功能(自由选择媒介类型的内容) 设计

1.首先明确需求 我想做一个可以选择媒介的内容&#xff0c;来进行发布媒介的功能 &#xff08;媒介包含&#xff1a;图片、文本、视频&#xff09; 2.原型设计 发布-编辑界面 通过点击下方的加号&#xff0c;可以自由选择添加的媒介类型 但是因为预览中无法看到视频的效果&…

行业分析---2024年小鹏汽车AI Day及三季度财报

1 背景 在之前的博客中&#xff0c;笔者撰写了多篇行业类分析的文章&#xff08;科技新能源&#xff09;&#xff1a; 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 《行业分析-…

数据可视化复习1-Matplotlib简介属性和创建子图

1.Matplotlib简介 Matplotlib是一个Python的2D绘图库&#xff0c;它可以在各种平台上以各种硬拷贝格式和交互环境生成具有出版品质的图形。通过Matplotlib&#xff0c;开发者可以仅需要几行代码&#xff0c;便可以生成绘图、直方图、功率谱、条形图、错误图、散点图等。 以下…

WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理

WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理 1. 标题识别elementUI组件爆红 这个原因是&#xff1a; 在官网说明里&#xff0c;才版本2024.1开始&#xff0c;默认启用的 Vue Language Server&#xff0c;但是在 Vue 2 项目…

如何安全删除 Linux 用户帐户和主目录 ?

Linux 以其健壮性和灵活性而闻名&#xff0c;是全球服务器和桌面的首选。管理用户帐户是系统管理的一个基本方面&#xff0c;包括创建、修改和删除用户帐户及其相关数据。本指南全面概述了如何在 Linux 中安全地删除用户帐户及其主目录&#xff0c;以确保系统的安全性和完整性。…

如何利用ros搭建虚拟场景通过仿真机器人完成一次简单的SLAM建图、导航规划(超简单)?——学习来源:机器人工匠阿杰

一&#xff1a;什么是SLAM&#xff0c;SLAM和导航规划又有什么关系&#xff1f; SLAM&#xff08;Simultaneous Localization and Mapping&#xff0c;即同时定位与建图&#xff09;是一种在未知或动态环境中自行驶的重要技术。主要通过设备上的传感器&#xff08;如激光雷达、…