Cypher 中的 TEXT 索引(Text Index)详解
一、什么是 TEXT 索引?
TEXT 索引(Text Index) 是 Neo4j 4.x 及以上版本提供的一种索引类型,专门用于对字符串属性进行精确匹配、前缀匹配 和 文本搜索。
- TEXT 索引适用于对大量字符串属性进行快速匹配,提高基于字符串属性的查询性能。
- TEXT 索引与 BTREE 索引不同,它更适合文本匹配操作,包括
STARTS WITH
、ENDS WITH
和CONTAINS
等操作。
二、TEXT 索引的特点
2.1 支持的操作
=
:精确匹配STARTS WITH
:前缀匹配ENDS WITH
:后缀匹配CONTAINS
:部分匹配
2.2 不适合范围查询
- TEXT 索引不适用于数值属性的范围匹配,应使用 BTREE 或 RANGE 索引。
2.3 适用于大量文本数据
- 适合在大规模字符串数据中执行快速匹配,提高查询效率。
三、创建 TEXT 索引
3.1 基本语法
CREATE TEXT INDEX FOR (n:Label) ON (n.property)
n:Label
:指定标签Label
的节点。n.property
:指定需要创建 TEXT 索引的属性。
3.2 为单个属性创建 TEXT 索引
CREATE TEXT INDEX FOR (n:Person) ON (n.name)
- 为
Person
标签的name
属性创建 TEXT 索引。 - 适用于对
name
属性进行前缀、后缀或部分匹配的查询。
3.3 创建复合 TEXT 索引(不支持)
- TEXT 索引不支持复合索引,仅能对单个属性创建索引。
3.4 为关系属性创建 TEXT 索引
CREATE TEXT INDEX FOR ()-[r:LIKES]-() ON (r.comment)
- 为
LIKES
关系的comment
属性创建 TEXT 索引。
四、查看和管理 TEXT 索引
4.1 查看当前数据库中的所有索引
SHOW INDEXES
- 显示所有索引,包括 BTREE、TEXT、RANGE 和 FULLTEXT 等索引。
4.2 查看特定 TEXT 索引
SHOW INDEXES YIELD name, type, labelsOrTypes, properties
YIELD
关键字筛选返回指定索引的相关信息。- TEXT 索引的
type
字段会显示TEXT
。
4.3 删除 TEXT 索引
DROP INDEX myTextIndex
- 删除
myTextIndex
索引。
DROP INDEX FOR (n:Person) ON (n.name)
- 删除
Person
标签name
属性上的 TEXT 索引。
五、TEXT 索引的查询优化
5.1 精确匹配(=)
MATCH (n:Person {name: 'Alice'})
RETURN n
- 使用 TEXT 索引对
name
属性进行精确匹配,提高查询速度。
5.2 前缀匹配(STARTS WITH
)
MATCH (n:Person)
WHERE n.name STARTS WITH 'Al'
RETURN n
- 通过
STARTS WITH
进行前缀匹配,可以利用 TEXT 索引进行查询。
5.3 后缀匹配(ENDS WITH
)
MATCH (n:Person)
WHERE n.name ENDS WITH 'ce'
RETURN n
- 通过
ENDS WITH
进行后缀匹配,TEXT 索引也可以优化这种查询。
5.4 部分匹配(CONTAINS
)
MATCH (n:Person)
WHERE n.name CONTAINS 'lic'
RETURN n
CONTAINS
会触发 TEXT 索引,实现部分字符串匹配。
5.5 使用 WHERE
进行字符串比较
MATCH (n:Product)
WHERE n.name = 'Smartphone'
RETURN n
- 使用
WHERE
子句结合=
进行精确匹配。
六、TEXT 索引的优化建议
6.1 为字符串属性创建 TEXT 索引
- 如果某个字符串属性经常被用作
MATCH
、WHERE
或RETURN
查询的条件,应考虑创建 TEXT 索引。
6.2 使用 EXPLAIN
和 PROFILE
查看查询计划
EXPLAIN MATCH (n:Person) WHERE n.name CONTAINS 'lic' RETURN n
EXPLAIN
显示查询计划,确认是否使用了 TEXT 索引。
PROFILE MATCH (n:Person) WHERE n.name STARTS WITH 'Al' RETURN n
PROFILE
执行查询并返回查询的详细信息,包括是否使用了 TEXT 索引。
6.3 避免 OR
导致索引失效
MATCH (n:Person)
WHERE n.name STARTS WITH 'Al' OR n.name ENDS WITH 'ce'
RETURN n
OR
逻辑通常不会触发索引,可以考虑拆分查询或使用UNION
。
6.4 TEXT 索引与 FULLTEXT 索引的区别
- TEXT 索引适用于精确匹配和前后缀匹配,但不适合复杂的全文搜索。
- 如果需要进行复杂的全文搜索,应考虑使用
FULLTEXT
索引。
七、TEXT 索引的使用案例
7.1 精确匹配查询
MATCH (n:Person)
WHERE n.name = 'Alice'
RETURN n
- 使用 TEXT 索引进行精确匹配,快速查找
name
为Alice
的Person
节点。
7.2 前缀匹配查询
MATCH (n:Person)
WHERE n.name STARTS WITH 'Al'
RETURN n
- 查找
name
以Al
开头的Person
节点,TEXT 索引优化前缀匹配。
7.3 后缀匹配查询
MATCH (n:Person)
WHERE n.name ENDS WITH 'ce'
RETURN n
- 查找
name
以ce
结尾的Person
节点。
7.4 部分匹配查询
MATCH (n:Person)
WHERE n.name CONTAINS 'lic'
RETURN n
- 查找
name
中包含lic
的Person
节点。
八、TEXT 索引的常见错误及解决方法
8.1 索引未生效
MATCH (n:Person)
WHERE n.name STARTS WITH 'A'
RETURN n
- 问题:TEXT 索引未生效。
- 解决方法:使用
EXPLAIN
或PROFILE
查看查询计划,确认是否使用了 TEXT 索引。
8.2 复合 TEXT 索引不被支持
CREATE TEXT INDEX FOR (n:Person) ON (n.firstName, n.lastName)
- 错误:TEXT 索引不支持复合索引。
- 解决方法:TEXT 索引只能对单个属性创建索引。
8.3 删除不存在的 TEXT 索引
DROP INDEX FOR (n:Person) ON (n.name)
- 错误:索引不存在时删除会报错,应先使用
SHOW INDEXES
查看现有索引。
九、TEXT 索引与 FULLTEXT 索引的区别
9.1 TEXT 索引
特性 | 描述 |
---|---|
索引类型 | TEXT 索引 |
支持的操作 | = 、STARTS WITH 、ENDS WITH 、CONTAINS |
适用场景 | 字符串的前后缀匹配和部分匹配 |
创建方式 | CREATE TEXT INDEX |
是否支持全文搜索 | 不支持 |
9.2 FULLTEXT 索引
特性 | 描述 |
---|---|
索引类型 | FULLTEXT 索引 |
支持的操作 | 全文搜索、模糊匹配 |
适用场景 | 需要进行复杂文本搜索的场景 |
创建方式 | CREATE FULLTEXT INDEX |
是否支持前缀匹配和部分匹配 | 不直接支持 |
9.3 何时使用 TEXT 索引 vs FULLTEXT 索引?
-
TEXT 索引:
- 适用于精确匹配、前缀匹配、后缀匹配和部分匹配。
- 查询速度更快,适合对字符串属性进行过滤和匹配。
-
FULLTEXT 索引:
- 适用于全文搜索和复杂文本匹配。
- 需要进行语义搜索、模糊搜索时使用 FULLTEXT 索引。
十、删除 TEXT 索引
10.1 删除特定索引
DROP INDEX FOR (n:Person) ON (n.name)
- 删除
Person
节点name
属性上的 TEXT 索引。
10.2 删除所有 TEXT 索引
SHOW INDEXES YIELD name
CALL {
WITH name
DROP INDEX name
}
- 删除数据库中所有 TEXT 索引。
十一、总结
- TEXT 索引 主要用于字符串属性的精确匹配、前缀匹配、后缀匹配和部分匹配,在处理大规模文本数据时可以显著提高查询性能。
- 创建 TEXT 索引时使用
CREATE TEXT INDEX
语法,并可以通过SHOW INDEXES
查看索引状态。 EXPLAIN
和PROFILE
可以帮助确认查询是否使用了 TEXT 索引。- TEXT 索引不能用于数值范围查询,也不支持复合索引,如果需要进行全文搜索,请使用
FULLTEXT
索引。
掌握 TEXT 索引的使用方法,可以帮助你优化 Neo4j 中字符串属性的查询性能,提高数据检索效率。