赞
踩
Neo4j系列导航:
neo4j安装及简单实践
cypher语法基础
cypher插入语法
cypher插入语法
cypher查询语法
cypher通用语法
cypher函数语法
neo4j索引及调优
节点矢量搜索索引在Neo4j 5.11中作为公测版本发布,在Neo4j 5.13中作为通用版本发布。
向量索引允许用户从大型数据集查询向量嵌入。嵌入是数据对象(如文本、图像、音频或文档)的数字表示。
例如,文本中的每个单词或标记通常表示为高维向量,其中每个维表示单词含义的某个方面。语义上相似或相关的词通常用向量空间中彼此更接近的向量来表示。这允许像加法和减法这样的数学运算带有语义意义。例如,“国王”减去“男人”加上“女人”的向量表示可能接近于“女王”的向量表示。换句话说,向量嵌入可以说是特定数据对象的数字表示,捕获其语义。
特定数据对象的嵌入可以通过例如Vertex AI或OpenAI嵌入生成器生成,它们可以生成维度为256、768、1536和3072的向量嵌入。这些向量嵌入存储为节点上的LIST<INTEGER | FLOAT>
属性,其中向量的每个维度组件都是LIST
中的一个元素。Neo4j矢量索引可以通过LIST<INTEGER | FLOAT>
属性对索引有效来索引节点。
在Neo4j中,矢量索引允许您根据节点属性与查询中指定的节点属性之间的相似性编写匹配节点邻域的查询。
Neo4j矢量索引由Apache Lucene索引和搜索库提供支持。Lucene实现了一个分层可导航的小世界(HNSW)图,在向量域上执行k个近似最近邻(k- ann)查询。
矢量索引通过Cypher®命令和内置程序进行管理,详情请参阅操作手册。
向量索引的步骤和命令:
使用 | 命令/程序 | 描述 |
---|---|---|
创建节点向量索引 | CREATE VECTOR INDEX ... | 使用给定的相似度函数,为具有给定向量维数的指定标签和属性创建向量索引,详 情请参照:db.index.vector.createNodeIndex 5.15版引入 |
创建关系向量索引 | CREATE VECTOR INDEX ... | 使用给定的相似性函数,为具有给定向量维数的指定关系类型和属性创建关系向量索引。有关详细信息,请参见CREATE INDEX命令。 5.18版引入 |
创建向量索引 | db.index.vector.createNodeIndex | 它被CREATE VECTOR INDEX… 取代。 |
使用节点向量索引 | db.index.vector.queryNodes | 查询给定节点向量索引。返回请求的最近邻节点的近似个数及其相似度分数,按分数排序。 |
使用关系向量索引 | db.index.vector.queryRelationships | 查询给定的关系向量索引。返回请求的近似最近邻关系的数目及其相似度分数,按分数排序。5.18版引入 |
删除向量索引 | DROP INDEX index_name | 删除指定索引,详情请参照drop index命令 |
列出所有向量索引 | SHOW VECTOR INDEXES | 列出所有矢量索引,详情请参照show index命令 5.15版引入 |
设置节点向量属性 | db.create.setNodeVectorProperty | 以比直接使用SET 命令更节省空间的方式用给定向量更新给定节点属性。取代db.create.setVectorProperty 5.13版引入 |
db.create.setVectorProperty | 被db.create.setNodeVectorProperty 取代 | |
设置关系向量属性 | db.create.setRelationshipVectorProperty | 以比直接使用SET 更节省空间的方式用给定的向量更新给定的关系属性 5.18版引入 |
create vector index
命令用来创建向量索引
CREATE VECTOR index $name FOR…
CREATE VECTOR INDEX
命令接受一个OPTIONS
子句。它有两个部分,indexProvider
和indexConfig
。从Neo4j 5.18开始,有两个可用的索引提供程序,vector-2.0(默认)
和vector-1.0
。indexConfig
是从STRING
值到STRING
和INTEGER
值的MAP
,用于设置特定于索引的配置设置(向量维度和相似性函数)。向量索引是节点的单标签、单属性索引,或者是关系的单关系类型、单属性索引。一个矢量索引需要配置矢量的维度(包括1到4096之间的INTEGER)和两个矢量之间的相似性度量(不区分大小写的STRING)。
创建矢量索引的语法
命令 描述 CREATE VECTOR INDEX [index_name] [IF NOT EXISTS] FOR (n:LabelName) ON (n.propertyName) OPTIONS "{" option: value[, ...] "}"
在节点上创建矢量索引。选项映射是强制性的,因为在创建矢量索引时必须设置矢量维度和相似性函数 CREATE VECTOR INDEX [index_name] [IF NOT EXISTS] FOR ()-”[“r:TYPE_NAME”]”-() ON (r.propertyName)OPTIONS "{" option: value[, ...] "}"
创建关系的矢量索引。选项映射是强制性的,因为在创建矢量索引时必须设置矢量维度和相似性函数 5.18版引入
索引中的所有向量必须具有相同的维数。相似度的度量由给定的向量相似度函数确定。这通过相似性评分定义了两个向量彼此之间的相似程度,如何解释向量,以及哪些向量对索引有效。
如果满足以下所有条件,节点或关系将被索引: 否则,不为节点或关系建立索引
LIST<INTEGER | FLOAT>
。size()
与配置的维度相同。例如,假设你有一个研究论文的图表,每篇论文都有一个摘要。你想在你熟悉的报纸附近找到报纸。
(:Title)<--(:Paper)-->(:Abstract)
假设对于每个摘要,您已经使用Open AI的text-embedding-ada-002
模型生成了摘要文本的1536-dimensional向量embedding
,这个模型表明了余弦相似性。有关更多信息,请参阅OpenAI的官方文档。
可以在嵌入属性上创建余弦节点矢量索引:
CREATE VECTOR INDEX `abstract-embeddings`
FOR (n: Abstract) ON (n.embedding)
OPTIONS {indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
}}
假设您有一个员工和他们的经理的图表,他们本身就是员工。经理们定期审查他们的报告,你希望搜索类似主题和细微差别的审查,以找到优秀的员工。
(:Manager)-[:REVIEWED]->(:Employee)
假设对于每个评论,您已经使用Open AI的文本嵌入-3-large模型的缩短生成了评论文本的256维向量嵌入。这个模型表明了余弦相似性。有关更多信息,请参阅OpenAI的官方文档。
可以在嵌入属性上创建余弦关系向量索引:
CREATE VECTOR INDEX `review-embeddings`
FOR ()-[r:REVIEWED]-() ON (r.embedding)
OPTIONS {indexConfig: {
`vector.dimensions`: 256,
`vector.similarity_function`: 'cosine'
}}
使用show indexes
SHOW VECTOR INDEXES YIELD name, type, entityType, labelsOrTypes, properties, options
结果:
name | type | entityType | labelsOrTypes | properties | options |
---|---|---|---|---|---|
“abstract-embeddings” | “VECTOR” | “NODE” | [“Abstract”] | [“embedding”] | {indexProvider: “vector-2.0”, indexConfig: {vector.dimensions: 1536, vector.similarity_function: “cosine”}} |
“review-embeddings” | “VECTOR” | “RELATIONSHIP” | [“REVIEWED”] | [“embedding”] | {indexProvider: “vector-2.0”, indexConfig: {vector.dimensions: 256, vector.similarity_function: “cosine”}} |
可以使用db.index.vector.queryNodes或db.index.vector.queryRelationships过程查询向量索引。
// 使用db.index.vector.queryNodes查询节点向量索引
db.index.vector.queryNodes(indexName :: STRING, numberOfNearestNeighbours :: INTEGER, query :: ANY) :: (node :: NODE, score :: FLOAT)
// 使用db.index.vector.queryRelationships查询关系向量索引
db.index.vector.queryRelationships(indexName :: STRING, numberOfNearestNeighbours :: INTEGER, query :: ANY) :: (relationship :: RELATIONSHIP, score :: FLOAT)
STRING
)是指要查询的矢量索引的唯一名称。INTEGER
)表示要返回的最近邻居的数目。LIST<INTEGER | FLOAT>
)。这些过程返回节点的邻域或关系及其各自的相似度分数,并按这些分数排序。分数在0到1之间,分数越接近1
,索引向量与查询向量越相似
。
查询节点向量索引:
// 本例以描述向量索引实现的HNSW[2]图结构的论文为例,并尝试查找类似的论文。首先使用MATCH来查找论文,
// 然后在abstract-embeddings索引中查询与查询内容相近的10个摘要。最后,匹配邻居各自的头衔。
MATCH (title:Title)<--(:Paper)-->(abstract:Abstract)
WHERE toLower(title.text) = 'efficient and robust approximate nearest neighbor search using
hierarchical navigable small world graphs'
CALL db.index.vector.queryNodes('abstract-embeddings', 10, abstract.embedding)
YIELD node AS similarAbstract, score
MATCH (similarAbstract)<--(:Paper)-->(similarTitle:Title)
RETURN similarTitle.text AS title, score
title | score |
---|---|
“Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs” | 1.0 |
“Accelerating Large-Scale Graph-based Nearest Neighbor Search on a Computational Storage Platform” | 0.9437285661697388 |
“Nearest Neighbor Search Under Uncertainty” | 0.9322342872619629 |
“Neighbor selection and hitting probability in small-world graphs” | 0.9316230416297913 |
“Towards Similarity Graphs Constructed by Deep Reinforcement Learning” | 0.9301378726959229 |
“A novel approach to study realistic navigations on networks” | 0.928106427192688 |
“Intentional Walks on Scale Free Small Worlds” | 0.9274556636810303 |
“FINGER: Fast Inference for Graph-based Approximate Nearest Neighbor Search” | 0.9267876148223877 |
“Learning to Route in Similarity Graphs” | 0.9263730049133301 |
结果是意料之中的,论文讨论了基于图的最近邻搜索。 |
与此结果最相似的是查询向量本身,这在使用索引属性查询索引时是可以预料到的。如果查询向量本身不需要,则可以使用WHERE score < 1
删除查询向量的等效向量。
查询关系向量索引:
// 这个例子使用一个查询向量来描述评论中的特定主题和细微差别。这个查询向量可以通过使用GenAI集成插件对
// 主题进行编码来获得。然后,您查询评论嵌入索引,查找包含与查询相似主题和细微差别的10条评论的邻域。最
// 后,匹配社区各自的雇员。
CALL db.index.vector.queryRelationships('review-embeddings', 10, $query)
YIELD relationship AS review, score
MATCH ()-[review]->(employee:Employee)
RETURN employee.name AS name, score
命令:DROP INDEX
DROP INDEX `abstract-embeddings`
用于索引的有效向量必须具有IEEE 754
1单精度中有限可表示的分量。它们被表示为类型为LIST<INTEGER | FLOAT>
的节点上的属性。从Neo4j 5.13开始,您可以使用db.create.setNodeVectorProperty
过程在节点上设置矢量属性。它验证输入并将属性设置为IEEE 754
单精度值的数组。这个测试过程取代了db.create.setVectorProperty
。从Neo4j 5.18开始,您可以使用db.create.setRelationshipVectorProperty
过程在关系上设置矢量属性。
db.create.setNodeVectorProperty(node :: NODE, key :: STRING, vector :: ANY)
// 后面废弃
db.create.setVectorProperty(node :: NODE, key :: STRING, vector :: ANY) :: (node :: NODE)
db.create.setRelationshipVectorProperty(relationship :: RELATIONSHIP, key :: STRING, vector :: ANY)
通过匹配节点并使用db.create.setNodeVectorProperty设置其向量属性:
MATCH (n:Node {id: $id})
CALL db.create.setNodeVectorProperty(n, 'propertyKey', $vector)
RETURN n
匹配一个关系并使用db.create.setRelationshipVectorProperty设置它的向量属性:
MATCH ()-[r:Relationship {id: $id}]->()
CALL db.create.setRelationshipVectorProperty(r, 'propertyKey', $vector)
RETURN r
使用set命令在节点上设置向量属性:
MATCH (node:Node {id: $id})
SET node.propertyKey = $vector
RETURN node
Cypher强制并存储提供的LIST<INTEGER | FLOAT>
作为IEEE 754双精度值的原始数组。与使用db.create.setNodeVectorProperty过程的替代方法相比,这几乎占用了两倍的空间
。因此,不建议对向量索引使用SET。
为了减少存储空间,您可以使用db.create.setNodeVectorProperty重置现有属性
。然而,这伴随着事务日志大小增加的成本,直到它们被旋转掉。
相似函数的选择影响到哪些索引向量被认为是相似的
,哪些是有效的
。向量的语义本身可以决定选择哪个相似函数。
名称 | 不区分大小写参数 | 关键相似性特征 |
---|---|---|
Euclidean(欧几里得) | “euclidean” | distance |
Cosine(余弦) | “cosine” | angle |
当两个向量之间的夹角决定了两个向量的相似度时,使用余弦相似度。
余弦向量索引的有效向量是:
余弦相似度解释了笛卡尔坐标中的向量。度量与两个向量之间的夹角有关。然而,一个角度可以用许多单位、符号约定和句号来描述。这个角的三角余弦与前面提到的角度约定无关,而且有界。余弦相似度反弹三角余弦。
在上面的方程中,三角余弦由两个单位向量的标量积给出。
从Neo4j 5.18开始,默认和首选的矢量索引提供程序是vector-2.0
。之前创建的vector-1.0
索引将继续发挥作用。如果指定,仍然可以使用vector-1.0
索引提供程序创建新索引
Supported | vector-1.0 | vector-2.0 |
---|---|---|
索引模式 | 节点的单标签、单属性索引。 没有关系支持 | 节点的单标签、单属性索引 关系的单一类型、单一属性索引 |
索引属性值类型 | LIST<FLOAT> | LIST<INTEGER/FLOAT> |
索引向量维数 | 1到2048之间的整数 | 1到4096之间的整数 |
余弦相似向量有效性 | 在IEEE 754中,所有矢量分量都可以用单精度有限表示; 它的e^2范数是非零的,在IEEE 754单精度中可以有限地表示 | 在IEEE 754双精度中,所有向量分量都可以有限地表示; 它的e^2范数是非零的,在IEEE 754双精度中可以有限地表示; 在IEEE 754单精度中,每个矢量分量与其e^2范数的比值可以有限地表示 |
从Neo4j 5.13开始,矢量搜索索引不再是一个测试版功能。
已知问题和测试的版本详见:官方问题及测试修复文档
向量索引可以利用孵化的Java 20矢量API来显著提高速度。如果你使用的是兼容的Java版本,你可以在你的配置设置中添加以下设置:
server.jvm.additional=--add-modules jdk.incubator.vector
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。