neo4j 5.19.0两种基于向量进行相似度查询的方式

article/2025/7/3 12:56:59

介绍

主要讲的是两种相似度查询

  1. 一种是创建向量索引,然后直接从索引的所有数据中进行相似度搜索,这种不支持基于自己查询的结果中进行相似度匹配
  2. 另一种是自己调用向量方法生产相似度进行相似度搜索,这种可以基于自己的查询结果中进行相似度搜索

相关地址

向量索引的创建、查询、删除等

在线向量字段生成(也有包含离线生成的相关模型的链接)

相似度算法 Function

测试数据集

基于向量索引进行相似度查询

创建向量字段

创建字段代码

此处主要讲离线的创建方式,在线的需要大模型的key ,需要联网,我没试过,但是开头有提供官网链接,需要的可以自己看。

本质都是查出需要建向量字段的所有数据,然后看需要用哪些字段生成向量字段,将这些字段拼接起来后调用模型生成向量后给对应的节点插入一个 embedding 字段

下面是用 bert 的模型生成的 768 维的 embedding

from neo4j import GraphDatabase
from transformers import BertTokenizer, BertModel
# from transformers import AutoTokenizer, AutoModelForMaskedLMclass Neo:def __init__(self, uri, user, password):self.driver = GraphDatabase.driver(uri, auth=(user, password))def close(self):self.driver.close()def listMovies(self):result =   self.driver.execute_query('match (n:Movie) return elementId(n) as id,n.description as description,n.name as name')return result.recordsdef writeMovieEmbedding(self,id,embedding):#插入embedding 字段result = self.driver.execute_query('match (n:Movie) where  elementId(n) = $id set n.embedding=$embedding',id=id,embedding=embedding)return result.recordsclass Embedding:def __init__(self):self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')self.model = BertModel.from_pretrained('bert-base-chinese')# self.tokenizer = AutoTokenizer.from_pretrained('bert-base-chinese')# self.model = AutoModelForMaskedLM.from_pretrained('bert-base-chinese')def gen(self,text):#根据文本生成embeddinginputs = self.tokenizer(text, return_tensors='pt')outputs = self.model(**inputs)pooler_output = outputs.pooler_output# pooler_output = outputs.logitsreturn pooler_output.detach().numpy()if __name__ == "__main__":em = Embedding()neo = Neo("bolt://192.168.91.128:7687", "neo4j", "12345678")movies = neo.listMovies()for record in movies:data = record.data()# 需要进行相似度查询的文本,可以从neo4j查出的结果字段拼接,也可以拼接其他自己想拼接的东西embeddingText = data.get('name')+","+data.get('description')embedding = em.gen(embeddingText)neo.writeMovieEmbedding(data.get("id"),embedding.tolist()[0])neo.close()

模型我是放在和代码同目录的地方,如下图所示

 效果如下图所示,多了个 embedding 字段

 相关依赖

下面是我使用的依赖和版本

python:3.8

torch:2.4.0

neo4j:5.28.1

transformers:4.46.3

向量模型下载

下面是我使用模型的下载地址,可以从网址中找到其他模型。你们也可以选择其他模型

官网,需要翻墙的地址

镜像地址,不需要翻墙,但不知道啥时候失效

创建向量索引

执行如下语句创建索引

CREATE VECTOR INDEX $indexName IF NOT EXISTS
FOR (m:Movie)
ON m.embedding
OPTIONS { indexConfig: {`vector.dimensions`: 768,`vector.similarity_function`: 'cosine'
}}

$indexName 是自己指定的索引名称,不要创建重复的名称。

FOR  后面的 (m:Movie) 用于配置查询条件指定给哪些数据创建索引

ON  后面的 m.embedding 用于指定用哪个字段创建索引,我创建的向量字段是 embedding

vector.dimensions 配置向量的维度,主要我们生成向量的模型用的什维度,此处就是什么维度,我上面用的模型生成的维度是768,所以没得就是768

vector.similarity_function:配置相似度的计算算法,consine 余弦相似度,euclidean 欧氏距离

向量相似度查询

这种查询方式我目前知道的只能基于索引内的全量数据进行相似度查询,而无法基于自己MATCH 之后的数据集进行相似度查询 

基本语法

CALL db.index.vector.queryNodes($indexName, $topK, $embedding)
YIELD node AS movie, score

$indexName 要查询的索引名称

$topK 设置要返回最相似的前面多少条

 $embedding 查询和这个向量字段相似的数据,double 数组

score 相似度分数,值越大表示越相似

直接从索引查询

这种查询会查询索引下所有数据匹配相似度,然后返回前5条

CALL db.index.vector.queryNodes('movie_idx', 5, $embedding)
YIELD node AS movie, score
RETURN movie.name AS name, movie.description AS description , score

 $embedding 需要自己将自己要查询的字符串生成向量数组后放进去查询,比如如果需要查询和“食物”相关的电影,将 “食物” 通过上面的模型生产向量,如生成向量的为 [1.8,2.7,3.5] ,则查询写法为

CALL db.index.vector.queryNodes('movie_idx', 5, [1.8,2.7,3.5] )
YIELD node AS movie, score
RETURN movie.name AS name, movie.description AS description, score

注意,此处生成的向量 $embedding 维度需要和索引的维度一致,假设量纲不匹配,如上面的[1.8,2.7,3.5] 才三个量纲,于是出现如下错误

Failed to invoke procedure `db.index.vector.queryNodes`: Caused by: java.lang.IllegalArgumentException: Index query vector has 3 dimensions, but indexed vectors have 768.

基于查询的结果进行相似度查询

MATCH (m:Movie {name: '食神'})
CALL db.index.vector.queryNodes('movie_idx', 5, m.embedding)
YIELD node AS movie, score
where movie.description contains '周星驰'
RETURN movie.name AS name, movie.description AS description, score

1. MATCH  查出一条名称为 "食神" 的节点

2.CALL 里的 m.embedding 表示用这条"食神" 的节点的 embedding 向量字段进行相似度匹配,找出和食神这部电影相似度最高的前五部电影。

注意:

1.前面的 MATCH 是可以返回多条数据的,假设前面的 MATCH 返回两个节点 "食神" ,"功夫",则循环每个节点调用一次后面的 CALL ,结果为和"食神"  相似度最高的五部电影加上和 功夫" 相似度最高的五部电影,总共十部电影。同理,如果返回的是十条数据,那就是得到五十部电影

2. CALL 里的 m.embedding 必须是MATCH的向量属性,不能自己输入向量数组,我一开始是自己输入向量数组,以为 CALL 是基于前面 MATCH  之后的结果集里进行相似度查询。结果返回的数据变成 5 的倍数,然后数据每 5 条重复一次。

3.where 是可以基于匹配结果进行过滤的

查询效果如下图所示

 基于Function进行相似度查询

这种方式是自己调用相似度算法生成相似度 Score 后排序获取最相似的数据,所以支持基于 Match 后的数据集进行相似度查询。这种方式不需要建索引。

MATCH (m:Movie)
WITH m, vector.similarity.cosine($embedding, m.vector) AS score
RETURN node, score
ORDER BY score DESCENDING
LIMIT 2;

1.MATCH 就是查询出自己需要的数据集

2.WITH 里调用 vector.similarity.cosine 生成余弦相似度作为 score,socre越高表示越相似

3.odder by + limit 就可以查出最相似的前几条数据了

4. $embedding 是向量数组,也是基于要查询的文本生产向量数组后放上去,同 直接从索引查询 的 $embedding  是一样的


http://www.hkcw.cn/article/gMAoUaBmbT.shtml

相关文章

中科院报道铁电液晶:从实验室突破到多场景应用展望

2020年的时候,相信很多关注科技前沿的朋友都注意到,中国科学院一篇报道聚焦一项有望改写显示产业格局的新技术 —— 铁电液晶(FeLC)。这项被业内称为 "下一代显示核心材料" 的研究,究竟取得了哪些实质性进展…

任务26:绘制1-12月各省份平均气温和预测可视化图形(折线

任务描述 知识点: DjangoECharts 重 点: DjangoECharts折线图 内 容: 绘制列表框,能够切换不同的省份根据ECharts官方示例,绘制ECharts折线图根据ECharts配置项手册,修改ECharts图形配置 任务指导…

【Redis】Set 集合

文章目录 常用命令saddsmemberssismemberscardspopsmovesrem 集合间操作sinter && sinterstoresunion && sunionstoresdiff && sdiffstore 内部编码应用场景 集合类型也是用于存储多个字符串类型的数据结构 集合中元素之间是 1. 无序的 2. 不允许重复的…

python打卡训练营打卡记录day43

复习日 作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 进阶:并拆分成多个文件 数据集来源:Flowers Recognition 选择该数据集原因: 中等规模:4242张图片 - 训练快速但足够展示效…

向量空间的练习题目

1.考虑 中的向量x1 和x2 求每一向量的长度 令x3x1x2,求x3的长度,它的长度与x1和x2的和有什么关系? 2.重复练习1,取向量 3.令C为复数集合,定义C上的加法为 (abi)(cdi)(ac)(bd)i 并定义标量乘法为对所有实数a (abi) a bi 证明&…

Android Studio历史版本下载地址汇总

Android Studio 下载文件归档 | Android Developers本页提供了各个 Android Studio 版本的下载归档文件。https://developer.android.google.cn/studio/archive?hlzh-cn

SpringBoot-Thymeleaf

大佬写的真好:Thymeleaf一篇就够了-阿里云开发者社区

序列搜索策略

序列搜索策略 贪心搜索(greedy search) 在大语言模型中, 对于输出序列的每一时间步t′, 我们都将基于贪心搜索从Y中找到具有最高条件概率的词元,即: y t ′ argmax ⁡ y ∈ Y P ( y ∣ y 1 , … , y t ′…

MG影视登录解锁永久VIP会员 v8.0 支持手机电视TV版影视直播软件

MG影视登录解锁永久VIP会员 v8.0 支持手机电视TV版影视直播软件 MG影视App电视版是一款资源丰富、免费便捷、且专为大屏优化的影视聚合应用,聚合海量资源,畅享电视直播,是您电视盒子和…

【浏览器】无法连接到互联网解决方法

Mac网络连接一切正常(手机连接互联网能正常使用) 但是涉及到网络界面就提示“无法连接到互联网”: 解决办法: 点击左上角→系统设置→网络→→位置→编辑位置→→新增一个即可 正常了!!

【C语言预处理详解(下)】--#和##运算符,命名约定,命令行定义 ,#undef,条件编译,头文件的包含,嵌套文件包含,其他预处理指令

目录 五.#和##运算符 5.1--#运算符 5.2--##运算符 六.命名约定,#undef,命令行定义 6.1--命名约定 6.2--#undef 6.3--命名行定义 七.条件编译 常见的条件编译指令: 1.普通的条件编译: 2.多个分支的条件编译(可以利用条…

数据资产评估进阶:精读资产评估专家指引第9号——数据资产评估指导【附全文阅读】

这篇文档是有关数据资产评估的专业报告,以下是文档中需要关注的重点内容: 1. 评估对象:文档中提到了数据资产评估的评估对象,即被评估数据资产。需要关注被评估数据资产的信息属性、法律属性、价值属性等,以及其特征对…

btstack协议栈---ESP32底层逻辑分析

目录 循环体 循环体中,怎么读取、处理数据 packet_handler 上面各层如何处理数据 谁触发了数据的传输? 硬件相关的数据有4类 循环体 BTStack针对不同的运行环境,抽象出了对应的btstack_run_loop结构体,共成员为: 比如其中的execute成员很重要,它是一个循环,在循…

碳中和新路径:铁电液晶屏如何破解高性能与节能矛盾?

一、显示技术困局:当 “高刷” 遭遇 “高耗” 在元宇宙、电竞产业蓬勃发展的当下,显示设备的刷新率与能耗成为行业痛点。传统液晶受 “边缘场效应” 制约,刷新率长期停滞在 300Hz 以下,动态画面拖影问题显著;同时&…

408考研逐题详解:2009年第27题

2009年第27题 一个分段存储管理系统中,地址长度为 32 位,其中段号占 8 位,则最大段长是( ) A. 2 8 2^8 28B \qquad B. 2 16 2^{16} 216B \qquad C. 2 24 2^{24} 224B \qquad D. 2 32 2^{32} 232B 解析 本题…

ASC格式惯导数据文件转IMR格式文件

我们使用惯导采集数据之后,如果需要用现有软件进行解算,比如POSMind等等,就会涉及到IMR格式的惯导数据文件。而NovAtel Convert转换软件只能将原始DAT格式的文件转成ASCLL文件,因此我自编程实现了ASC格式文件到IMR格式文件的转换。…

电脑为什么换个ip就上不了网了

在日常使用电脑上网时,很多人可能遇到过这样的问题:当IP地址发生变化后,突然就无法连接网络了。当电脑更换IP地址后无法上网,这一现象可能由多种因素导致,涉及网络配置、硬件限制或运营商策略等层面。以下是系统性分析…

动中通天线跟踪性能指标的测试

卫星通信动中通天线包括天线、卫星信号跟踪接收机、GNSS接收机(含天线)、组合导航设备、天线控制器、伺服结构以及其他射频组件等。其中: • GNSS接收机提供系统位置信息; • 组合导航设备提供天线所在平台的方位、俯仰、横滚姿态…

从 GPT 的发展看大模型的演进

这是一个技术爆炸的时代。一起来看看 GPT 诞生后,与BERT 的角逐。 BERT 和 GPT 是基于 Transformer 模型架构的两种不同类型的预训练语言模型。它们之间的角逐可以从 Transformer 的编码解码结构角度来分析。 BERT(Bidirectional Encoder Representatio…

Charles青花瓷抓取外网数据包

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! Charles有一个问题,开启翻墙工具后会发现无法进行抓包,这是需要做额外的配置才可以 首选选择下图中的External Proxy Settings 然后如下…