agentic_huge_data_base / wiki
页面 Graphiti · 7.3 提供方-专属查询生成·DeepWiki 中文全文译文

7.3 · 提供方-专属查询生成(Provider-Specific Query Generation)

时序知识图谱与动态事实记忆 · 聚焦本章的模块关系、源码依据与实现要点。

项目Graphiti 章节7.3 状态全文译文 模块检索、召回与索引、图谱与关系、测试、发布与运维、模型调用与提供方适配
源码线索
  • examples/podcast/podcast_runner.py
  • graphiti_core/driver/record_parsers.py
  • graphiti_core/models/edges/edge_db_queries.py
  • graphiti_core/models/nodes/node_db_queries.py
  • graphiti_core/search/search.py
  • graphiti_core/search/search_config.py
  • graphiti_core/search/search_config_recipes.py
  • graphiti_core/search/search_utils.py
  • tests/test_graphiti_int.py
模块标签
  • 检索、召回与索引
  • 图谱与关系
  • 测试、发布与运维
  • 模型调用与提供方适配
  • 入库与解析

章节正文

提供方-专属查询生成

特定于提供商的查询生成

相关源文件

本章引用的主要源码文件:

  • examples/podcast/podcast_runner.py
  • graphiti_core/driver/record_parsers.py
  • graphiti_core/models/edges/edge_db_queries.py
  • graphiti_core/models/nodes/node_db_queries.py
  • graphiti_core/search/search.py
  • graphiti_core/search/search_config.py
  • graphiti_core/search/search_config_recipes.py
  • graphiti_core/search/search_utils.py
  • tests/test_graphiti_int.py

本文档介绍了 Graphiti 如何针对不同的图数据库提供商调整 Cypher 查询和搜索操作。虽然 Graphiti 使用 Cypher 作为主要查询语言,但每个数据库后端(Neo4j、FalkorDB、Kuzu、Neptune)都有独特的语法要求、函数可用性和数据处理模式,这些都需要在查询时进行适配。

关于驱动程序初始化和连接管理的信息,请参阅图数据库驱动程序。关于索引创建语法,请参阅索引和约束管理

目的与范围

Graphiti 中的查询生成遵循一个多阶段流程:

  1. 通用 Cypher 构建:核心搜索逻辑和数据库操作模型使用通用模式构建标准 Cypher 查询。
  2. 提供商适配:在执行之前,会根据 GraphProvider 枚举 graphiti_core/driver/driver.py:28-28 修改或完全替换查询,以匹配特定数据库的语法。
  3. 搜索接口卸载:对于复杂的搜索任务,GraphDriver 可能会委托给特定于提供商的 search_interfacegraph_operations_interface graphiti_core/search/search_utils.py:134-138

查询构建管线

下图说明了搜索请求如何从高级 search 函数流经处理提供商特定分支的实用函数。

搜索查询流程
Graphiti · 搜索查询流程 · 图 1
Graphiti · 搜索查询流程 · 图 1

来源: graphiti_core/search/search.py:98-108graphiti_core/search/search_utils.py:85-113graphiti_core/search/search_filters.py:56-60

提供商语法差异

下表总结了各提供商之间的关键查询语法差异:

特性Neo4jKuzuFalkorDBNeptune
全文搜索Lucene(无前缀)仅简单 Tokenbuild_fulltext_queryOpenSearch(AOSS)
向量类型转换原生原生vecf32($vector)字符串分隔
边建模原生关系RelatesToNode_ 节点原生关系原生关系
数组处理原生数组原生数组原生数组分隔字符串(join/split
批量保存UNWIND单独迭代UNWINDUNWIND

来源: graphiti_core/search/search_utils.py:85-113graphiti_core/models/nodes/node_db_queries.py:30-171graphiti_core/models/edges/edge_db_queries.py:63-122graphiti_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 · 实现空间到代码的映射 · 图 2
Graphiti · 实现空间到代码的映射 · 图 2

来源: graphiti_core/search/search_utils.py:85-113graphiti_core/models/nodes/node_db_queries.py:142-149graphiti_core/models/edges/edge_db_queries.py:84-102graphiti_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 episode graphiti_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 的 joinsplit 函数将列表属性作为分隔字符串进行管理。

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-134graphiti_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_atvalid_atinvalid_atgraphiti_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-108graphiti_core/nodes.py:21-21

搜索配置与重排序

查询生成也受 SearchConfig 的影响。根据所选的 search_methods(例如 bm25cosine_similarity),Graphiti 会生成不同的查询片段或调用不同的提供商特定搜索例程。

  • 混合搜索:使用 RRF(倒数排序融合)或 MMR(最大边际相关性)等算法组合来自多种方法的结果 graphiti_core/search/search_config.py:32-77
  • 过滤器构建node_search_filter_query_constructoredge_search_filter_query_constructor 生成针对提供商语法定制的 WHERE 子句 graphiti_core/search/search_utils.py:213-215

来源: graphiti_core/search/search_config.py:32-129graphiti_core/search/search_utils.py:185-224