第 07 篇把 LOOKUP / RANGE / TEXT / POINT 钉成自动参与计划的搜索性能索引。本篇只划边界:FULLTEXT 与 VECTOR 是另一类——手册称 semantic indexes,底层都挂 Apache Lucene,内存叙事走 OS 文件系统缓存,查询默认不会被 Cypher 规划器悄悄选用。倒排与 ANN 的全书分别在站内 全文检索引擎 与 向量检索引擎;此处只回答「它们如何接在属性图旁边」。
本文是「图数据库内核」系列第 8 篇(共 16 篇)。→ 系列目录
篇目 核心内容 第 7 篇 · 索引与约束 LOOKUP / RANGE / TEXT / POINT 第 8 篇 · 全文与向量边界 Lucene 旁路、内存、查询入口、混合检索 第 9 篇 · Expand 拓扑扩张(与语义召回拼接)
版本锚定:Cypher Manual 5 Full-text indexes;Cypher Manual current Vector indexes(含 2025.10 / 2026.01 能力注记);Operations Manual(2026.07 / current)Vector index memory configuration、Memory configuration。站内互链以相对
.html为准。
一、三层「搜字符串 / 搜相似」,不要混成一种索引
| 机制 | 典型谓词 / 用法 | 规划器 | 实现直觉 |
|---|---|---|---|
| RANGE / TEXT(第 07 篇) | 等值、前缀、CONTAINS/ENDS WITH
等 |
自动选用 | Native;进 page cache 规划 |
| FULLTEXT | 分词后的内容匹配 + score;Lucene 查询语法 | 不自动选用;调过程 | Lucene;偏 OS 缓存 |
| VECTOR | 嵌入近邻 + score;可与过滤组合 | 过程或 SEARCH(新版本优先) |
Lucene + HNSW 配置;OS 缓存 |
TEXT INDEX
手册写明:只做有限字符串匹配;近似匹配、打分、语义解读走
full-text。VECTOR 则根本不在「字符串算子」轨道上——属性是
LIST<FLOAT>(及更新版本的原生
VECTOR 类型),比的是几何/余弦相似度。
flowchart TB
Prop["Node/Rel STRING or embedding property"]
Prop --> Native["RANGE / TEXT / POINT<br/>page cache"]
Prop --> FT["FULLTEXT<br/>Lucene"]
Prop --> Vec["VECTOR<br/>Lucene + HNSW params"]
Native --> Plan["Cypher planner auto"]
FT --> Proc["queryNodes / queryRelationships"]
Vec --> Proc2["queryNodes / SEARCH"]
Proc --> Expand["Optional: expand topology"]
Proc2 --> Expand
语义召回给出候选集合 \(S\) 之后,若还要走关系,代价回到第 02–05 篇的 expand——向量分不能替代 hop。
二、Full-text:分词、打分、显式查询
2.1 与 TEXT 的本质差别
Cypher Manual 5:full-text 把 STRING
拆成词(token)再索引,从而匹配属性内容;并返回查询串与存储值之间的接近分数。底层:Apache
Lucene。分析器可选(如 english
停用词表);db.index.fulltext.listAvailableAnalyzers()
列出可用分析器。
创建形态(示意):
CREATE FULLTEXT INDEX namesAndTeams IF NOT EXISTS
FOR (n:Employee|Manager)
ON EACH [n.name, n.team]
OPTIONS {
indexConfig: {
`fulltext.analyzer`: 'english',
`fulltext.eventually_consistent`: true
}
}
- 多标签用
|;关系类型同理可建在边上。 fulltext.eventually_consistent: true:更新在后台尽快应用,不在事务提交路径上与多数索引一样同步维护——写延迟与读可见性之间的显式交换(对照第 06 篇「提交时维护索引」的默认故事)。
2.2 查询入口
手册硬规则:full-text 不会被规划器自动使用。必须:
CALL db.index.fulltext.queryNodes("namesAndTeams", "nils")
YIELD node, score
RETURN node.name, score
关系侧用
db.index.fulltext.queryRelationships。查询串支持
Lucene 布尔算子、字段限定等(手册指向 Lucene Query Parser
文档)。score
降序;分数只在同一次查询结果集内可比。
2.3 站内分工
Analyzer、postings、BM25、Segment 生命周期 → search-engine。本系列只要求记住:图库里的 FULLTEXT 是嵌入的 Lucene 索引,不是第三种邻接 store。
三、Vector:嵌入属性上的近邻索引
3.1 产品事实(手册)
- 向量索引同样由 Lucene 驱动;配置项暴露
HNSW 参数(如
vector.hnsw.m默认 16,vector.hnsw.ef_construction等)。 - 嵌入存在节点或关系属性上:传统为
LIST<FLOAT>;2025.10+ 可更高效存为原生VECTOR类型(Cypher 25 路径)。Community 可索引 LIST;原生 VECTOR 存储与 block format 绑定(EE / Aura 能力边界——手册脚注)。 - 维度:配置
vector.dimensions推荐显式给出;设置范围手册写 1–3200(含)。未设维度时不同维度可并存于同一索引,但仅同维可比较——易混淆,故推荐创建时钉死维度。 - 相似度:
vector.similarity_function(如cosine/ 欧氏相关选项);文本嵌入常用 cosine。 - 2026.01+:多标签/多关系类型;可用
WITH附加非向量属性供过滤——不是多向量属性的复合向量索引;每个实体仍只索引一个向量属性。
创建示意:
CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie) ON (m.embedding)
OPTIONS {
indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: 'cosine'
}
}
3.2 查询入口
- 2026.01+ 优先:Cypher
SEARCH子句(可带过滤;与手册 SEARCH … WHERE 路径对齐)。 - 兼容旧版:
db.index.vector.queryNodes/queryRelationships(手册注明过程在 2026.04 起弃用叙事——以你部署版本为准)。
分数落在 \([0,1]\)(越近越大),仅在同一次向量查询结果内有序有意义。与 full-text 或其它打分源做混合检索时,手册要求:各源独立排序/融合,不要直接横比原始 score。
拓扑嵌入(GDS 等写出的结构向量)也可建向量索引——信号是图结构而非文本语义;仍是「属性上的 ANN」,不是 expand。
3.3 站内分工
HNSW / DiskANN / 专用引擎 Segment → vector-engine 与 db-frontier 向量索引。GraphRAG 编排 → db-frontier / llm-infra;第 16 篇再收选型。本篇不推导召回率曲线。
四、内存:为什么「加大 pagecache」救不了向量查询
Operations Manual Vector index memory configuration(A 级):
- Lucene 向量索引文件由 OS filesystem cache 缓存,不是 Neo4j page cache。
- 必须在 heap + page cache 之外留足 RAM;不够则向量搜索反复读盘,压力大时 OS 还可能 swap。
- 容量启发式(起点,非 SLA):
- 逻辑向量体积 \(\approx 4\,\mathrm{B} \times d \times n\)(FLOAT32);
- 物理索引体积按是否量化、
HNSW_M估算(手册给每向量公式); - 量化开启时 OS 缓存约物理索引的 40%;未量化约 100%。
- 访问模式分叉:
- 只搜不回读向量属性 → page cache 主要服务其余图数据;
- 搜完还要投影/重排向量属性 → page cache 也要为向量属性页留份额。
- Warm-up:索引随查询装入 OS
缓存;重启清空。手册起点:小索引(\(\le
10^6\))约数次随机查询;更大索引可从约 100
次代表性查询调起,并用
iotop等看磁盘读是否收敛。
Full-text 同属 Lucene 家族:运维上与「Lucene 体积 vs
剩余内存」同一谈判桌(第 05 篇 memory-recommendation 已把
Lucene 总量与 page cache 对照)。不要把 FULLTEXT/VECTOR
的变慢默认诊断成 hit_ratio 问题。
五、和拓扑内核如何拼
| 模式 | 合理拼法 | 常见误用 |
|---|---|---|
| 语义入口 → 图约束 | vector/fulltext 得 \(S\),再 MATCH
过滤标签或短 expand |
以为 ANN 已「理解」关系类型 |
| 图过滤 → 语义重排 | 先用 RANGE/LOOKUP/expand 收窄,再对候选算向量分 | 全库向量顶 \(k\) 后再做昂贵多跳 |
| 混合检索 | 全文与向量各查各的,分源融合 | 把两种 score 当同一量纲相加 |
| GraphRAG | 图提供多跳证据;向量提供段落召回 | 用向量库替代强一致边(第 16 篇) |
写入侧:向量/全文属性更新触发 Lucene 维护(full-text 可 eventual);大嵌入写入还放大 store 与(若回读)page cache——第 06 篇写放大清单要多两行「语义索引」。
六、争论与开放问题
- 图库内嵌向量 vs 专用向量引擎:A 侧要单系统事务与「搜完即 expand」;B 侧要极致 ANN 吞吐与独立扩缩。边界用工作负载说话:候选集是否必须强一致落在同一事务快照;QPS/维度是否超出嵌入 Lucene 舒适区——详见 vector-engine 选型篇,本篇不排名。
- 同步索引 vs eventually_consistent full-text:可见性 vs 提交延迟;审计边与搜索边常应分开语义。
- 开放问题:多标签向量索引 +
过滤下的召回偏差;原生
VECTOR+ block 与 LIST 属性在故障恢复上的差异;混合融合算法(RRF 等)与图基数估计如何联立(第 10、16 篇)。
谱系:倒排(全文引擎系列)与 HNSW(Malkov & Yashunin 等,见 frontier/vector-engine)在 Neo4j 里共享「Lucene 插件位」,但没有变成第 03 篇那种关系链。
七、来源与实验台账(本篇)
| 结论 | 等级 | 来源 |
|---|---|---|
| Full-text:Lucene、非自动计划、过程查询、analyzer、eventually_consistent | A | Cypher Manual 5 Full-text indexes |
| Vector:Lucene、HNSW 配置、维度、相似度、SEARCH/过程、多标签 2026.01 | A | Cypher Manual current Vector indexes |
| 向量内存:OS cache、非 page cache、40%/100% 启发式、warm-up、访问模式 | A | Operations Manual Vector index memory configuration |
| TEXT vs full-text 职责 | A | 第 07 篇所引 Search-performance indexes |
| 本机 ANN/QPS | 未跑 | 不写延迟数字 |
八、小结
- FULLTEXT / VECTOR = Lucene 旁路语义索引;RANGE/TEXT 才是 page cache 叙事里的自动过滤器。
- 查询要显式:过程或
SEARCH;分数不可跨源裸比。 - 内存三角:heap × page cache ×
OS(Lucene);加大
pagecache.size不等于向量变快。 - 下一篇:在索引起点(含语义入口)之后,Expand 如何按类型与方向把拓扑走完。
→ 系列目录 · 上一篇:索引与约束 · 下一篇:遍历与 Expand
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【图数据库内核】图引擎全景:属性图作为一等公民的存储与遍历
定位属性图相对行存/LSM/向量/GraphRAG 的生态位;钉住邻接代价、Neo4j store format(record→block)、page cache、索引与 Expand、Cypher 计划五条坐标系,并以 Angles & Gutierrez 谱系与原生图争论收束系列路线。
【图数据库内核】邻接的代价模型:边表 JOIN、CSR 与原生指针为何不是同一件事
把同一逻辑图落成边表+索引、CSR、原生关系链与 Neo4j block 内联四条路径,用统一代价语言比较一次 hop 与 k 跳扩张;钉住幂律超节点与局部性,为后续 record/block 布局篇垫底座。
【图数据库内核】Neo4j record 系布局:节点、关系链、属性链与 dense group
以 Neo4j 5.26 record-storage-engine 源码钉住 standard/aligned 固定记录:15B 节点、34B 关系、41B 属性、25B relationship group;讲清 sparse 链、dense 阈值与一次 hop 的指针路径。
【图数据库内核】Neo4j Block format:128 B 主块、动态溢出与 dense B+ 树
对照第 03 篇 record 指针链,钉住 Enterprise 推荐的 block 布局:block.x1.db 128 B 主块、node/relationship 动态 store、big_values、relationship dense 多根 B+ 树与实体上限;重写一次 hop 的读路径。