提供方-专属查询生成
特定于提供商的查询生成
相关源文件
本章引用的主要源码文件:
examples/podcast/podcast_runner.pygraphiti_core/driver/record_parsers.pygraphiti_core/models/edges/edge_db_queries.pygraphiti_core/models/nodes/node_db_queries.pygraphiti_core/search/search.pygraphiti_core/search/search_config.pygraphiti_core/search/search_config_recipes.pygraphiti_core/search/search_utils.pytests/test_graphiti_int.py
本文档介绍了 Graphiti 如何针对不同的图数据库提供商调整 Cypher 查询和搜索操作。虽然 Graphiti 使用 Cypher 作为主要查询语言,但每个数据库后端(Neo4j、FalkorDB、Kuzu、Neptune)都有独特的语法要求、函数可用性和数据处理模式,这些都需要在查询时进行适配。
关于驱动程序初始化和连接管理的信息,请参阅图数据库驱动程序。关于索引创建语法,请参阅索引和约束管理。
目的与范围
Graphiti 中的查询生成遵循一个多阶段流程:
- 通用 Cypher 构建:核心搜索逻辑和数据库操作模型使用通用模式构建标准 Cypher 查询。
- 提供商适配:在执行之前,会根据
GraphProvider枚举graphiti_core/driver/driver.py:28-28修改或完全替换查询,以匹配特定数据库的语法。 - 搜索接口卸载:对于复杂的搜索任务,
GraphDriver可能会委托给特定于提供商的search_interface或graph_operations_interfacegraphiti_core/search/search_utils.py:134-138。
查询构建管线
下图说明了搜索请求如何从高级 search 函数流经处理提供商特定分支的实用函数。
搜索查询流程
来源: graphiti_core/search/search.py:98-108、graphiti_core/search/search_utils.py:85-113、graphiti_core/search/search_filters.py:56-60
提供商语法差异
下表总结了各提供商之间的关键查询语法差异:
| 特性 | Neo4j | Kuzu | FalkorDB | Neptune |
|---|---|---|---|---|
| 全文搜索 | Lucene(无前缀) | 仅简单 Token | build_fulltext_query | OpenSearch(AOSS) |
| 向量类型转换 | 原生 | 原生 | vecf32($vector) | 字符串分隔 |
| 边建模 | 原生关系 | RelatesToNode_ 节点 | 原生关系 | 原生关系 |
| 数组处理 | 原生数组 | 原生数组 | 原生数组 | 分隔字符串(join/split) |
| 批量保存 | UNWIND | 单独迭代 | UNWIND | UNWIND |
来源: graphiti_core/search/search_utils.py:85-113、graphiti_core/models/nodes/node_db_queries.py:30-171、graphiti_core/models/edges/edge_db_queries.py:63-122、graphiti_core/models/edges/edge_db_queries.py:30-51
全文搜索与向量操作
全文查询适配
全文搜索需要大量的适配,因为每个提供商使用不同的底层引擎。search_utils.py 中的 fulltext_query 辅助函数集中了此逻辑。
- Kuzu:仅支持简单查询;长查询会被截断以防止错误
graphiti_core/search/search_utils.py:88-92。 - FalkorDB:委托给
driver.build_fulltext_query,该函数使用 RedisSearch 语法graphiti_core/search/search_utils.py:93-94。 - Neo4j:使用标准 Lucene 语法,通过
fulltext_syntax属性使用group_id过滤器添加前缀graphiti_core/search/search_utils.py:95-113。
实现空间到代码的映射
来源: graphiti_core/search/search_utils.py:85-113、graphiti_core/models/nodes/node_db_queries.py:142-149、graphiti_core/models/edges/edge_db_queries.py:84-102、graphiti_core/search/search_utils.py:225-227
向量处理
- FalcorDB:在保存操作期间需要使用
vecf32()包装向量graphiti_core/models/nodes/node_db_queries.py:147-147。 - Kuzu:使用原生数组,但需要为边使用一个中间节点
RelatesToNode_来存储fact_embedding属性graphiti_core/models/edges/edge_db_queries.py:88-94。 - Neptune:在保存期间使用
join()将嵌入向量序列化为逗号分隔的字符串graphiti_core/models/edges/edge_db_queries.py:80-80。
节点与边持久化
批量操作
批量保存操作在支持的地方(Neo4j、FalkorDB、Neptune)使用 UNWIND。Kuzu 是一个值得注意的例外,对于某些边类型,它可能需要单独处理。
graphiti_core/models/nodes/node_db_queries.py:69-109:
- Neptune/FalkorDB/Neo4j:使用
UNWIND $episodes AS episodegraphiti_core/models/nodes/node_db_queries.py:73-108。 - Kuzu:使用单个节点
MERGE模式,通常以迭代方式调用graphiti_core/models/nodes/node_db_queries.py:81-93。
Neptune 属性序列化
Neptune 不支持所有属性的原生数组。Graphiti 使用 Cypher 的 join 和 split 函数将列表属性作为分隔字符串进行管理。
graphiti_core/models/nodes/node_db_queries.py:36-36:
entity_edges: join([x IN coalesce($entity_edges, []) | toString(x) ], '|')
graphiti_core/models/nodes/node_db_queries.py:133-133:
split(e.entity_edges, ",") AS entity_edges
来源: graphiti_core/models/nodes/node_db_queries.py:30-134、graphiti_core/models/edges/edge_db_queries.py:138-148
数据解析与记录映射
一旦查询返回结果,record_parsers.py 模块负责将原始数据库行转换回 Pydantic 模型。此层抽象了提供商在属性和标签返回方式上的差异。
关键解析函数:
entity_node_from_record:通过删除内部键来清理属性,并处理动态组标签graphiti_core/driver/record_parsers.py:24-50。entity_edge_from_record:映射关系属性,包括时间字段(expired_at、valid_at、invalid_at)graphiti_core/driver/record_parsers.py:53-85。episodic_node_from_record:确保存在强制性的时间字段,并将源字符串转换为EpisodeType枚举graphiti_core/driver/record_parsers.py:88-108。
来源: graphiti_core/driver/record_parsers.py:24-108、graphiti_core/nodes.py:21-21
搜索配置与重排序
查询生成也受 SearchConfig 的影响。根据所选的 search_methods(例如 bm25、cosine_similarity),Graphiti 会生成不同的查询片段或调用不同的提供商特定搜索例程。
- 混合搜索:使用 RRF(倒数排序融合)或 MMR(最大边际相关性)等算法组合来自多种方法的结果
graphiti_core/search/search_config.py:32-77。 - 过滤器构建:
node_search_filter_query_constructor和edge_search_filter_query_constructor生成针对提供商语法定制的WHERE子句graphiti_core/search/search_utils.py:213-215。
来源: graphiti_core/search/search_config.py:32-129、graphiti_core/search/search_utils.py:185-224