一、 简介

本博客针对Neo4j 3.5版本,原始内容请见官方文档:https://neo4j.com/docs/cypher-manual/3.5/schema/index/

Neo4j的全文索引采用Lucene,能够对neo4j中string类型的属性建立全文索引。

  1. 能够同时为node和relationship的属性建立索引。而neo4j内嵌的索引仅能够对node的属性建立索引。
  2. 至于字符串如何被切分和索引,取决于为lucene配置的analyzer。支持自定义Analyzer,包括lucene中没有提供的。
  3. 能够用lucene查询语句进行查询;
  4. 能够返回相似度score;
  5. 能够随着节点和关系的添加、移除、修改进行自动的更新;
  6. 自动检查一致性,如果有不一致的问题自动重建;
  7. 在单个索引中,能够支持任意数目的文档;
  8. 创建、删除、更新都是事务的,能够在集群中自动进行副本;
  9. 能够通过cypher语句访问.
  10. 能够配置为满足最终一致性。即,索引更新在提交路径中被移除,转为后台线程。利用此特性,对于性能要求高的场景,能够消除主要的写瓶颈。

相比于Neo4j内嵌的索引,采用Lucene索引具有如下优势:

  1. neo4j的内嵌索引采用b树,其仅能够对STARTS WITH、ENDS WITH、完全相等三种条件起作用。而lucene建立的全文索引能够对任意片段的字符串进行查询。
  2. lucene索引能够对多个label建立.
  3. lucene索引能够对一到多个关系建立.
  4. 能够同时应用于多个属性。与内嵌索引的Composite Index不同。Composite Index仅对满足label且同时具有所有属性的实体起作用,而全文索引则对至少满足一个label、关系类型、属性的节点或关系起作用.

二、使用

1. 常用操作
采用neo4j的内生procedure来管理全文索引。最常用的procedure在下文列示。

功能

过程

描述

创建全文节点索引

db.index.fulltext.createNodeIndex

参数包括:

1. 全局唯一的索引名称(类型为string);

2. labels(类型为string list);

3. properties(类型为string list);

4. config(可选的,是个key和value都为string类型的map)。config可以指定要建立索引的Analyzer(通过analyzer属性),还可以指定是否采用最终一致性模式(通过eventually_consistent)。

创建全文关系索引

db.index.fulltext.createRelationshipIndex

参数包括:

1. 全局唯一的索引名称(类型为string);

2. relationship types(类型为string list);

3. properties(类型为string list);

4. config(可选的,是个key和value都为string类型的map)。config可以指定要建立索引的Analyzer(通过analyzer属性),还可以指定是否采用最终一致性模式(通过eventually_consistent)。

使用全文节点索引

db.index.fulltext.queryNodes

参数:

1. 索引名称

2. lucene查询语句

返回:

1. 匹配到的节点

2. lucene得分按照score降序返回

使用全文关系索引

db.index.fulltext.queryRelationships

参数:

1. 索引名称

2. lucene查询语句

返回:

1. 匹配到的关系

2. lucene得分按照score降序返回

删除索引

db.index.fulltext.drop

参数:

1. 索引名称

最终一致性索引

db.index.fulltext.awaitEventuallyConsistentIndexRefresh

等待最新提交的事务在最终一致性全文索引中生效。

列出可用的Analyzer

db.index.fulltext.listAvailableAnalyzers

列出全文索引可用的所有Analyzer。lucene中已经内置了多种语言的analyzer。

2. 创建和配置全文索引
例如,想要对于Label为Movie和Book的节点创建索引,索引的字段包括title和description。则采用如下cypher语句。

CALL db.index.fulltext.createNodeIndex("titlesAndDescriptions",["Movie", "Book"],["title", "description"])

想要使用以上索引搜索标题或者描述中包含“matrix”的节点,调用如下cypher语句。

CALL db.index.fulltext.queryNodes("titlesAndDescriptions", "matrix") YIELD node, score
RETURN node.title, node.description, score

创建关系索引,以及可选参数config的使用。

CALL db.index.fulltext.createRelationshipIndex("taggedByRelationshipIndex",["TAGGED_AS"],["taggedByUser"], { analyzer: "url_or_email", eventually_consistent: "true" })

3. 使用全文索引进行查询

CALL db.index.fulltext.queryNodes("titlesAndDescriptions", "Full Metal Jacket") YIELD node, score
RETURN node.title, score

可以用Lucene的全文检索语法,例如,如果需要完全匹配,则加双引号

CALL db.index.fulltext.queryNodes("titlesAndDescriptions", "\"Full Metal Jacket\"") YIELD node, score
RETURN node.title, score

可以使用逻辑操作符,例如AND OR

CALL db.index.fulltext.queryNodes("titlesAndDescriptions", 'full AND metal') YIELD node, score
RETURN node.title, score

还可以对指定的属性进行查询。

CALL db.index.fulltext.queryNodes("titlesAndDescriptions", 'description:"surreal adventure"') YIELD node, score
RETURN node.title, node.description, score

4. 删除全文索引

CALL db.index.fulltext.drop("taggedByRelationshipIndex")