土法炼钢兴趣小组的算法知识备份

【图数据库内核】全文与向量属性边界:Lucene 旁路,不是 page cache 里的第二套邻接

文章导航

分类入口
databasegraph
标签入口
#graph-database#neo4j#fulltext#vector-index#lucene#hnsw#hybrid-search#rag#semantic-index

目录

07 篇把 LOOKUP / RANGE / TEXT / POINT 钉成自动参与计划的搜索性能索引。本篇只划边界:FULLTEXTVECTOR 是另一类——手册称 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 configurationMemory 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
  }
}

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 产品事实(手册)

创建示意:

CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie) ON (m.embedding)
OPTIONS {
  indexConfig: {
    `vector.dimensions`: 1536,
    `vector.similarity_function`: 'cosine'
  }
}

3.2 查询入口

分数落在 \([0,1]\)(越近越大),仅在同一次向量查询结果内有序有意义。与 full-text 或其它打分源做混合检索时,手册要求:各源独立排序/融合,不要直接横比原始 score

拓扑嵌入(GDS 等写出的结构向量)也可建向量索引——信号是图结构而非文本语义;仍是「属性上的 ANN」,不是 expand。

3.3 站内分工

HNSW / DiskANN / 专用引擎 Segment → vector-enginedb-frontier 向量索引。GraphRAG 编排 → db-frontier / llm-infra;第 16 篇再收选型。本篇不推导召回率曲线。


四、内存:为什么「加大 pagecache」救不了向量查询

Operations Manual Vector index memory configuration(A 级):

  1. Lucene 向量索引文件由 OS filesystem cache 缓存,不是 Neo4j page cache。
  2. 必须在 heap + page cache 之外留足 RAM;不够则向量搜索反复读盘,压力大时 OS 还可能 swap。
  3. 容量启发式(起点,非 SLA):
    • 逻辑向量体积 \(\approx 4\,\mathrm{B} \times d \times n\)(FLOAT32);
    • 物理索引体积按是否量化、HNSW_M 估算(手册给每向量公式);
    • 量化开启时 OS 缓存约物理索引的 40%;未量化约 100%
  4. 访问模式分叉
    • 只搜不回读向量属性 → page cache 主要服务其余图数据;
    • 搜完还要投影/重排向量属性 → page cache 也要为向量属性页留份额。
  5. 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 篇写放大清单要多两行「语义索引」。


六、争论与开放问题

  1. 图库内嵌向量 vs 专用向量引擎:A 侧要单系统事务与「搜完即 expand」;B 侧要极致 ANN 吞吐与独立扩缩。边界用工作负载说话:候选集是否必须强一致落在同一事务快照;QPS/维度是否超出嵌入 Lucene 舒适区——详见 vector-engine 选型篇,本篇不排名。
  2. 同步索引 vs eventually_consistent full-text:可见性 vs 提交延迟;审计边与搜索边常应分开语义。
  3. 开放问题:多标签向量索引 + 过滤下的召回偏差;原生 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 未跑 不写延迟数字

八、小结

  1. FULLTEXT / VECTOR = Lucene 旁路语义索引;RANGE/TEXT 才是 page cache 叙事里的自动过滤器。
  2. 查询要显式:过程或 SEARCH;分数不可跨源裸比。
  3. 内存三角:heap × page cache × OS(Lucene);加大 pagecache.size 不等于向量变快。
  4. 下一篇:在索引起点(含语义入口)之后,Expand 如何按类型与方向把拓扑走完。

系列目录 · 上一篇:索引与约束 · 下一篇:遍历与 Expand

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。


By .