neo4j使用详解(十五、索引之语义索引<全文索引>——最全参考)

请添加图片描述


Neo4j系列导航:
neo4j安装及简单实践
cypher语法基础
cypher插入语法
cypher插入语法
cypher查询语法
cypher通用语法
cypher函数语法
neo4j索引及调优


与搜索性能索引不同,语义索引捕获数据库中数据的语义或上下文。这是通过返回近似分数来完成的,该近似分数指示查询字符串与数据库中的数据之间的相似性。
Neo4j 中有两个可用的语义索引:

  • Full-text indexes(全文索引): 支持在STRING属性的内容中进行搜索,并支持查询字符串与存储在数据库中的STRING值之间的相似性比较

  • Vector indexes(向量索引): 通过将节点或属性表示为多维空间中的向量,支持相似性搜索复杂的分析查询

与搜索性能索引不同,语义索引不会被Cypher®规划器自动使用。要使用语义索引,必须用特定的过程显式地调用它们。

1.语义索引简介

全文索引用于按STRING属性为节点和关系建立索引。

  • 与范围索引和文本索引不同,全文索引只能执行有限的STRING匹配(精确匹配、前缀匹配、子字符串匹配或后缀匹配),
    全文索引在任何给定的STRING属性中存储单个单词。这意味着全文索引可用 于在STRING属性的内容内进行匹配。
  • 全文索引还返回给定查询字符串与存储在数据库中的string值之间的接近度评分,从而使它们能够在语义上解释数据。
  • 全文索引由Apache Lucene 索引和搜索库提供支持。

2.示例图数据

创建图谱:

CREATE (nilsE:Employee {name: "Nils-Erik Karlsson", position: "Engineer", team: "Kernel", peerReviews: ['Nils-Erik is difficult to work with.', 'Nils-Erik is often late for work.']}),
(lisa:Manager {name: "Lisa Danielsson", position: "Engineering manager"}),
(nils:Employee {name: "Nils Johansson", position: "Engineer", team: "Operations"}),
(maya:Employee {name: "Maya Tanaka", position: "Senior Engineer", team:"Operations"}),
(lisa)-[:REVIEWED {message: "Nils-Erik is reportedly difficult to work with."}]->(nilsE),
(maya)-[:EMAILED {message: "I have booked a team meeting tomorrow."}]->(nils)

在这里插入图片描述

3.创建全文索引

3.1.创建语法

创建命令: CREATE FULLTEXT INDEX index_name 名称未指定则随机分配

  • CREATE FULLTEXT INDEX命令可以是幂等的
  • 从Neo4j 5.16开始,索引名也可以作为参数给出,CREATE FULLTEXT index $name FOR…
  • 创建全文索引需要CREATE INDEX权限
  • 在创建全文索引时,需要指定它应该应用的标签/关系类型和属性名称。
    示例一:
    下面的语句为每个带有Employee或Manager标签的节点的name和team属性创建一个名为namesAndTeams的全文索引:
// 在节点标签和属性组合上创建全文索引
CREATE FULLTEXT INDEX namesAndTeams FOR (n:Employee|Manager) ON EACH [n.name, n.team]

这个查询突出了全文索引和搜索性能索引之间的两个关键区别:

  • 全文索引可以应用于多个节点标签。
  • 全文索引可以应用于多个属性,但与复合搜索性能索引不同,全文索引存储至少具有一个索引标签或关系类型以及至少一个索引属性的实体。

类似地,虽然关系只能有一种类型,但全文索引可以存储多种关系类型。在这种情况下,将包括匹配至少一个关系类型和至少一个索引属性的所有类型。

示例二:
下面的语句在message属性上为关系类型review和email创建了一个名为communications的全文索引:

// 在关系类型和属性组合上创建全文索引
CREATE FULLTEXT INDEX communications FOR ()-[r:REVIEWED|EMAILED]-() ON EACH [r.message]

3.2.标记和分析器

全文索引将单个单词存储在STRING属性中。这是通过tokenizer实现的,它将字符流分解为单个标记(通常是单个单词)。如何对
STRING进行标记 是由配置全文索引的分析器决定的。默认分析器(standard-no-stop-words)分析索引值和查询字符串。

停止词是一种语言中的常用词,可以在信息检索任务中过滤掉,因为它们被认为在确定字符串的含义时用处不大。这些词通常很短,经常在各种上下文中使用。
例如, Lucene的英语分析器中包含以下停止词:“a”、“an”、“and”、“are”、“as”、“at”、“be”、“but”等等。
删除停止字有助于减少存储数据的大小,从而提高数据检索的效率。

3.3.配置设置

CREATE FULLTEXT INDEX命令接受一个可选的OPTIONS子句,其中可以指定indexConfig
示例:
下面的语句使用标签为 Employee或Manager的节点的参数创建一个全文索引。Neo4j 5.16中引入了使用参数创建和删除索引。

{
  "name": "peerReviews"
}

使用OPTIONS创建全文索引:

CREATE FULLTEXT INDEX $name FOR (n:Employee|Manager) ON EACH [n.peerReviews]
OPTIONS {
  indexConfig: {
    `fulltext.analyzer`: 'english', //@1
    `fulltext.eventually_consistent`: true //@2
  }
}
  1. fulltext.analyzer分析器设置可用于配置特定于索引的分析器。在本例中,它被设置为英语分析器。fulltext.analyzer
    可以使用db.index.fulltext.listAvailableAnalyzers过程列出分析器设置。
  2. fulltext.eventually_consistent设置,如果设置为true,将使索引处于最终一致的更新模式。这意味着更新将“尽快”在后台线程
    中应用,而不是在事务提交期间,这对其他索引来说是正确的。
    有关如何配置全文索引的更多信息,请参见《操作手册——支持全文搜索的索引》

4.查询全文索引

4.1.查询语法

与其他搜索性能索引不同,全文索引不会被Cypher®查询规划器自动使用。要访问全文索引,必须使用上述过程显式地调用它们。

  • 示例一:

    使用db.index.fulltext.queryNodes在前面创建的全文索引namesAndTeams中查找nils:

    // 查询节点属性的全文索引
    CALL db.index.fulltext.queryNodes("namesAndTeams", "nils") YIELD node, score
    RETURN node.name, score
    

    结果:

    node.namescore
    “Nils Johansson”0.3300700783729553
    “Nils-Erik Karlsson”0.27725890278816223

    分数列表示索引认为条目与给定查询字符串匹配的程度。因此,除了任何精确匹配之外,全文索引还返回与给定查询字符串的近似
    匹配。这是可能的,因为索引的属性值和对索引的查询都是通过分析器处理的,这样索引就可以找到与所提供的STRING不完全匹
    配的数据实体

    分数结果总是按分数降序返回,其中最匹配的结果条目放在前面。


  • 示例二:
    这个查询使用db.index.fulltext.queryRelationships来查询前面创建的包含“meeting”的communications全文索引:

    // 查询关系属性的全文索引
    CALL db.index.fulltext.queryRelationships("communications", "meeting") YIELD relationship, score
    RETURN type(relationship), relationship.message, score
    

    结果:

    type(relationship)relationship.messagescore
    “EMAILED”“I have booked a team meeting tomorrow.”0.3239005506038666
  • 示例三:
    为了只获得精确匹配,引用你正在搜索的字符串:

    // 查询全文索引以获得精确匹配
    CALL db.index.fulltext.queryNodes("namesAndTeams", '"Nils-Erik"') YIELD node, score
    RETURN node.name, score
    

    结果:

    node.namescore
    “Nils-Erik Karlsson”0.7588480710983276
  • 示例四:
    查询字符串也支持使用Lucene布尔运算符 (AND, OR, NOT, +, -):

    //使用逻辑运算符查询全文索引
    CALL db.index.fulltext.queryNodes("namesAndTeams", 'nils AND kernel') YIELD node, score
    RETURN node.name, node.team, score
    

    结果:

    node.namenode.teamscore
    “Nils-Erik Karlsson”“Kernel”0.723090410232544
  • 示例五:
    通过在查询字符串前加上<propertyName>前缀,可以将搜索限制为特定的属性。

    // 查询特定属性的全文索引
    CALL db.index.fulltext.queryNodes("namesAndTeams", 'team:"Operations"') YIELD node, score
    RETURN node.name, node.team, score
    

    结果:

    node.namenode.teamscore
    “Nils Johansson”“Operations”0.21363800764083862
    “Maya Tanaka”“Operations”0.21363800764083862

Lucene查询语法的完整描述可以在Lucene文档 中找到。

4.2.字符串值列表

如果索引属性包含STRING值列表,则独立分析每个条目,并且所有生成的令牌都与相同的属性名称相关联。这意味着在查询这样的索引节点或关系时,如果任何列表元素与查询字符串匹配,则存在匹配。出于评分目的,全文索引将其视为单个属性值,分数将表示查询与匹配整个列表的接近程度。

  • 示例:
    // 查询STRING属性列表中显示的内容的全文索引
    CALL db.index.fulltext.queryNodes('peerReviews', 'late') YIELD node, score
    RETURN node.name, node.peerReviews, score
    
    结果:
    node.namenode.peerReviewsscore
    “Nils-Erik Karlsson”[“Nils-Erik is difficult to work with.”, “Nils-Erik is often late for work.”]0.13076457381248474

5.show全文索引

要列出数据库中所有的全文索引,使用SHOW FULLTEXT INDEXES 命令。

// 显示数据库中的所有全文索引
SHOW FULLTEXT INDEXES
idnamestatepopulationPercenttypeentityTypelabelsOrTypespropertiesindexProviderowningConstraintlastReadreadCount
4“communications”“ONLINE”100.0“FULLTEXT”“RELATIONSHIP”[“REVIEWED”, “EMAILED”][“message”]“fulltext-1.0”NULL2023-10-31T15:06:10.270Z2
3“namesAndTeams”“ONLINE”100.0“FULLTEXT”“NODE”[“Employee”, “Manager”][“name”, “team”]“fulltext-1.0”NULL2023-10-31T15:07:48.874Z5
6“peerReviews”“ONLINE”100.0“FULLTEXT”“NODE”[“Employee”, “Manager”][“peerReviews”]“fulltext-1.0”NULL2023-10-31T15:09:05.391Z3

与搜索性能索引类似,SHOW命令可以过滤特定的列:

// 使用过滤显示全文索引
SHOW FULLTEXT INDEXES WHERE name CONTAINS "Team"
idnamestatepopulationPercenttypeentityTypelabelsOrTypespropertiesindexProviderowningConstraintlastReadreadCount
5“namesAndTeams”“ONLINE”100.0“FULLTEXT”“NODE”[“Employee”, “Manager”][“name”, “team”]“fulltext-1.0”NULLNULL0

要返回完整的索引详细信息,请使用YIELD子句

// 显示所有全文索引和所有返回列
SHOW FULLTEXT INDEXES YIELD *
idnamestatepopulationPercenttypeentityTypelabelsOrTypespropertiesindexProviderowningConstraintlastReadreadCount
4“communications”“ONLINE”100.0“FULLTEXT”“RELATIONSHIP”[“REVIEWED”, “EMAILED”][“message”]“fulltext-1.0”NULLNULL0
5“namesAndTeams”“ONLINE”100.0“FULLTEXT”“NODE”[“Employee”, “Manager”][“name”, “team”]“fulltext-1.0”NULLNULL0
6“peerReviews”“ONLINE”100.0“FULLTEXT”“NODE”[“Employee”, “Manager”][“peerReviews”]“fulltext-1.0”NULLNULL0

有关所有返回列的完整描述,请参见搜索性能索引——结果列

6.删除全文索引

命令: DROP INDEX 与其他索引类似
从数据库中删除先前创建的communications全文索引:

DROP INDEX communications

从Neo4j 5.16开始,索引名也可以作为删除索引时的参数:DROP index $name

7.全文索引程序列表

全文索引的步骤如下表所示:

使用程序/命令描述
最终一致的索引db.index.fulltext.awaitEventuallyConsistentIndexRefresh等待来自最近提交的事务的更新应用于任何最终一致的全文索引。
列出可用的分析器db.index.fulltext.listAvailableAnalyzers列出可以配置全文索引的可用分析程序。
使用全文节点索引db.index.fulltext.queryNodes查询给定的全文索引。返回匹配节点和它们的Lucene查询分数,按分数排序
使用全文关系索引db.index.fulltext.queryRelationships查询给定的全文索引。返回匹配关系和它们的Lucene查询分数,按分数排序

8.总结

  • 全文索引支持节点和关系的索引。
  • 全文索引只包括STRING或LIST类型的属性值。
  • 全文索引是通过Cypher过程访问的。
  • 全文索引返回查询的每个结果的分数。
  • 全文索引支持配置自定义分析器,包括Lucene本身不包含的分析器。
  • 全文索引可以使用Lucene查询语言进行查询。
  • 随着节点和关系的添加、删除和修改,全文索引自动保持最新。
  • 全文索引将自动用存储中的现有数据填充新创建的索引。
  • 全文索引可以由一致性检查器检查,如果有问题可以重新构建。
  • 新创建的全文索引将自动使用数据库中的现有数据填充。
  • 全文索引可以在单个索引中支持任意数量的属性。
  • 全文索引以事务方式创建、删除和更新,并在整个集群中自动复制。
  • 全文索引可以配置为最终一致,其中索引更新从提交路径移动到后台线程。使用这个特性,可以在性能关键的提交过程中解决缓慢的Lucene写入问题,从而消除Neo4j写入性能的主要瓶颈。
  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Neo4j索引分为两种类型:节点索引和关系索引。其中,ci索引是节点索引,用于索引节点属性,而ct索引是关系索引,用于索引关系属性。 使用ci索引: 1. 创建索引neo4j中创建ci索引的语法如下: CREATE INDEX ON :Label(property) 其中Label是节点标签,property是要索引的节点属性。 例如,要在Person节点上创建一个索引来加速根据name属性查找该节点的操作,可以使用以下命令: CREATE INDEX ON :Person(name) 2. 使用索引 使用ci索引的语法如下: MATCH (n:Label) WHERE n.property = value RETURN n 其中Label是节点标签,property是要索引的节点属性,value是要查找的属性值。 例如,要查找名为Tom的Person节点,可以使用以下命令: MATCH (p:Person) WHERE p.name = 'Tom' RETURN p 使用ct索引: 1. 创建索引neo4j中创建ct索引的语法如下: CREATE INDEX ON :Type(property) 其中Type是关系类型,property是要索引的关系属性。 例如,要在Friend关系上创建一个索引来加速根据since属性查找该关系的操作,可以使用以下命令: CREATE INDEX ON :Friend(since) 2. 使用索引 使用ct索引的语法如下: MATCH (n1)-[r:Type]->(n2) WHERE r.property = value RETURN n1, r, n2 其中Type是关系类型,property是要索引的关系属性,value是要查找的属性值。 例如,要查找由Tom和Jerry之间的since属性为2020的Friend关系,可以使用以下命令: MATCH (tom)-[f:Friend]->(jerry) WHERE f.since = 2020 RETURN tom, f, jerry
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值