neo4j使用存储过程实现全文索引和查询,内部是基于lucene
一、举例
创建和配置全文索引 例如,对Label为Movie和Book的节点创建索引,索引的字段包括title和description。则采用如下cypher语句。
CALL db.index.fulltext.createNodeIndex
("titlesAndDescriptions",["Movie", "Book"],["title", "description"])
使用以上索引搜索 title 或者 description 中包含“matrix”的节点,调用如下cypher语句。
CALL db.index.fulltext.queryNodes
("titlesAndDescriptions", "matrix") YIELD node, score
RETURN node.title, node.description, score
解释: CALL 调用一个存储过程, YIELD 存放得到的结果, 用于下面的处理, 比如
call db.labels() yield label
return count(label) as num
查询举例2:
call db.index.fulltext.queryNodes(
'index_name', // 这里索引名
'Av' // lucene查询语句
) yield node
where node.address contains "12" // where语句
return node
order by node.address // order skip limit
skip 0
limit 1
Lucene搜索语法, 详细参考 https://www.jianshu.com/p/d924405e8db8 https://www.cnblogs.com/xing901022/p/4974977.html
Query implementation | Purpose | Example |
---|---|---|
TermQuery | 单词匹配 | neo4j |
PhraseQuery | 短语匹配 | "graph database" |
RangeQuery | 范围匹配 | [A TO Z] {A TO Z} |
WildcardQuery | 正则匹配 | g*p?, d??abase |
PrefixQuery | 前缀匹配 | algo* |
FuzzyQuery | 后缀匹配 | cipher~ |
BooleanQuery | 查询条件聚合 | graph AND "shortest path" |
可以用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
二、常用的几个存储过程:
1、创建全文节点索引 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)。
2、创建全文关系索引 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)。
3、使用全文节点索引 db.index.fulltext.queryNodes 参数:
1. 索引名称
2. lucene查询语句
返回:
3. 匹配到的节点
4. lucene得分按照score降序返回
4、使用全文关系索引 db.index.fulltext.queryRelationships 参数:
1. 索引名称
2. lucene查询语句
返回:
3. 匹配到的关系
4. lucene得分按照score降序返回
5、删除索引 db.index.fulltext.drop 参数:索引名称
6、最终一致性索引 db.index.fulltext.awaitEventuallyConsistentIndexRefresh 等待最新提交的事务在最终一致性全文索引中生效。
7、列出可用的Analyzer db.index.fulltext.listAvailableAnalyzers 列出全文索引可用的所有Analyzer。lucene中已经内置了多种语言的analyzer。
三、优点
Neo4j从2.2.x时代开始就默认开启node_auto_indexing=true. 倒排索引在数据插入时候已经创建了. 创建索引/删除索引代价是非常小的
官方文档:https://neo4j.com/docs/cypher-manual/3.5/schema/index/
-
支持关系与节点的索引,为node和relationship的属性建立索引
-
支持常用
analyzers
扩展 ,支持自定义Analyzer -
可以使用
lucene query
语句 -
可以返回查询结果评分
-
能够随着节点和关系的添加、移除、修改进行自动的更新
-
自动检查一致性,如果有不一致的问题自动重建;
-
创建、删除、更新都是事务的,能够在集群中自动进行副本;
-
单索引文档数量不限
-
能够通过cypher语句访问.
-
能够配置为满足最终一致性。即,索引更新在提交路径中被移除,转为后台线程。利用此特性,对于性能要求高的场景,能够消除主要的写瓶颈。
相比于Neo4j内嵌的索引,采用Lucene索引具有如下优势:
1、neo4j的内嵌索引采用b树,其仅能够对STARTS WITH、ENDS WITH、完全相等三种条件起作用。而lucene建立的全文索引能够对任意片段的字符串进行查询。
2、lucene索引能够对多个label建立.
3、lucene索引能够对一到多个关系建立.
4、能够同时应用于多个属性。与内嵌索引的Composite Index不同。Composite Index仅对满足label且同时具有所有属性的实体起作用,而全文索引则对至少满足一个label、关系类型、属性的节点或关系起作用.
四、使用中文分词器:
自带的分词器,其中有一个是“cjk”是针对中国,日本,韩国做的分词器,支持中文分词的,可以这样建索引:
在可选参数config配置使用的分词器:
CALL db.index.fulltext.createNodeIndex("companyFullIndex",["CompanyEntry"],["name"], { analyzer: "cjk"})
使用IK分词器:
五、与Elasticsearch结合使用