agentic_huge_data_base / wiki
页面 Graphiti · 10.4 SearchFilters 与时序查询·DeepWiki 中文全文译文

10.4 · SearchFilters 与时序查询

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

项目Graphiti 章节10.4 状态全文译文 模块图谱与关系、测试、发布与运维、检索、召回与索引、界面与交互
源码线索
  • examples/podcast/podcast_runner.py
  • graphiti_core/search/search.py
  • graphiti_core/search/search_config.py
  • graphiti_core/search/search_config_recipes.py
  • graphiti_core/search/search_filters.py
  • graphiti_core/search/search_utils.py
  • tests/test_graphiti_int.py
模块标签
  • 图谱与关系
  • 测试、发布与运维
  • 检索、召回与索引
  • 界面与交互
  • 模型调用与提供方适配

章节正文

SearchFilters 与时序查询

搜索过滤器与时序查询

相关源文件

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

  • examples/podcast/podcast_runner.py
  • graphiti_core/search/search.py
  • graphiti_core/search/search_config.py
  • graphiti_core/search/search_config_recipes.py
  • graphiti_core/search/search_filters.py
  • graphiti_core/search/search_utils.py
  • tests/test_graphiti_int.py

本文档记录了 SearchFilters Pydantic 模型及其所有关联的过滤器类型、运算符和 graphiti_core/search/search_filters.py 中的查询构造工具。它解释了如何通过节点标签、边类型、特定边 UUID、属性值和时序范围(事实有效时间、创建时间和过期时间)来限定搜索范围。

有关搜索架构的整体概述(包括搜索方法、重排序器和 SearchConfig),请参见第 4.3 页。有关调整搜索配置选项,请参见第 10.2 页。有关作为时序过滤基础的双时序数据模型,请参见第 3.2 页。

概述

Graphiti 中的每个搜索调用都接受一个 SearchFilters 实例,该实例会贯穿所有底层搜索方法(BM25 全文搜索、余弦相似度、BFS 遍历)。过滤器会在数据库查询执行前转换为 Cypher WHERE 子句。不同的图数据库提供商(Neo4j、FalkorDB、Kuzu、Neptune)会收到略有不同的语法。

数据模型图:SearchFilters 及其组件

Graphiti · 概述 · 图 1
Graphiti · 概述 · 图 1

来源:graphiti_core/search/search_filters.py:55-67

ComparisonOperator

ComparisonOperator 是一个 Python Enum,其值为 Cypher 运算符字符串。

成员Cypher 值说明
equals=精确匹配
not_equals<>不相等
greater_than>严格晚于/大于
less_than<严格早于/小于
greater_than_equal>=在或晚于/大于等于
less_than_equal<=在或早于/小于等于
is_nullIS NULL属性必须不存在/为空
is_not_nullIS NOT NULL属性必须存在且非空

当使用 is_nullis_not_null 时,DateFilter 上的 date 字段(或 PropertyFilter 上的 property_value 字段)会被忽略——不会向查询中发出参数。

来源:graphiti_core/search/search_filters.py:27-35

DateFilter

DateFilter 将一个 datetime 值与一个 ComparisonOperator 配对。它始终在 SearchFilterslist[list[DateFilter]] 字段内使用——从不单独使用。

class DateFilter(BaseModel):
    date: datetime | None = Field(default=None, description='用于过滤的日期时间')
    comparison_operator: ComparisonOperator = Field(
        description='日期过滤器的比较运算符'
    )

来源:graphiti_core/search/search_filters.py:38-42

PropertyFilter

PropertyFilter 允许对任意边或节点属性值进行过滤。

class PropertyFilter(BaseModel):
    property_name: str = Field(description='属性名称')
    property_value: str | int | float | None = Field(
        default=None, description='要匹配的属性值'
    )
    comparison_operator: ComparisonOperator = Field(
        description='属性的比较运算符'
    )

来源:graphiti_core/search/search_filters.py:45-52

SearchFilters

SearchFilters 是一个 Pydantic BaseModel,它将所有过滤条件聚合到一个单一对象中,并传递给每个搜索函数。它包含一个针对 node_labels 的验证器,以防止 Cypher 注入。

字段类型适用范围描述
node_labelslist[str] | None节点和边限制为带有这些标签的节点。对于边搜索,源节点(n)和目标节点(m都必须具有该标签。
edge_typeslist[str] | None仅边匹配 e.name——关系名称/类型。
edge_uuidslist[str] | None仅边限制为特定的边 UUID。
valid_atlist[list[DateFilter]] | None仅边过滤 e.valid_at——事实在现实世界中为真的时间。
invalid_atlist[list[DateFilter]] | None仅边过滤 e.invalid_at——事实变为假的时间。
created_atlist[list[DateFilter]] | None仅边过滤 e.created_at——边被入库的时间。
expired_atlist[list[DateFilter]] | None仅边过滤 e.expired_at——边被取代的时间。
property_filterslist[PropertyFilter] | None节点和边自定义属性过滤器。

来源:graphiti_core/search/search_filters.py:55-73

时序过滤逻辑:AND / 或嵌套

所有四个时序字段(valid_atinvalid_atcreated_atexpired_at)都接受 list[list[DateFilter]]。这种嵌套编码了一种析取范式(DNF)

  • 内部列表list[DateFilter])——条件通过 AND 组合。
  • 外部列表list[list[DateFilter]])——分组通过 OR 组合。

图:时序过滤器字段的 DNF 结构

Graphiti · 时序过滤逻辑:AND · 图 2
Graphiti · 时序过滤逻辑:AND · 图 2

来自集成测试 tests/test_graphiti_int.py:63-70 的示例生成的 Cypher 子句等效于: (e.created_at IS NULL) OR (e.created_at < $created_at_0) OR (e.created_at IS NOT NULL)

要表达一个范围(例如,在两个时间戳之间创建的边),请将两个 DateFilter 实例放在同一个内部列表中:

created_at=[
    [
        DateFilter(date=start_dt, comparison_operator=ComparisonOperator.greater_than_equal),
        DateFilter(date=end_dt,   comparison_operator=ComparisonOperator.less_than),
    ]
]
# 生成:(e.created_at >= $created_at_0 AND e.created_at < $created_at_1)

来源:graphiti_core/search/search_filters.py:149-262tests/test_graphiti_int.py:63-70

查询构造函数

图:过滤器构造和搜索管线

Graphiti · 查询构造函数 · 图 3
Graphiti · 查询构造函数 · 图 3

来源:graphiti_core/search/search_filters.py:86-262graphiti_core/search/search_utils.py:185-294graphiti_core/search/search_utils.py:440-573

node_search_filter_query_constructor

graphiti_core/search/search_filters.py:86-104

处理 node_labels。返回一个 (list[str], dict) 元组,包含 Cypher WHERE 片段及其绑定的参数。它对标签执行深度防御验证 graphiti_core/search/search_filters.py:95

提供商生成的子句
Neo4j / FalkorDB / Neptunen:Label1|Label2
Kuzulist_has_all(n.labels, $labels)
edge_search_filter_query_constructor

graphiti_core/search/search_filters.py:120-262

处理所有适用于边的过滤器字段。处理顺序:

  1. edge_typese.name in $edge_types
  2. edge_uuidse.uuid in $edge_uuids
  3. node_labelsn:<labels> AND m:<labels>(两个端点)
  4. valid_atinvalid_atcreated_atexpired_at → DNF 子句。

所有生成的子句被收集到一个列表中,并在 search_utils.py 的调用点通过 AND 连接。

date_filter_query_constructor

graphiti_core/search/search_filters.py:107-117

构建一个单一的日期比较字符串,例如 (e.valid_at < $valid_at_0)。对于 is_nullis_not_null 运算符,不会发出参数占位符。

SearchFilters 如何与搜索集成

图:SearchFilters 从 Graphiti.search_ 到数据库的流程

Graphiti · SearchFilters 如何与搜索集成 · 图 4
Graphiti · SearchFilters 如何与搜索集成 · 图 4

来源:graphiti_core/search/search.py:98-108graphiti_core/search/search_utils.py:185-294graphiti_core/search/search_utils.py:440-573

提供商特定行为

特性Neo4j / FalkorDBKuzuNeptune
节点标签过滤n:A|Blist_has_all(n.labels, $labels)n:A|B
时序过滤Cypher WHERE 子句相同的 Cypher 子句Cypher WHERE 子句
OpenSearch 运算符映射不适用不适用全文搜索使用 cypher_to_opensearch_operator()

cypher_to_opensearch_operator 函数 graphiti_core/search/search_filters.py:76-83ComparisonOperator 值映射到 OpenSearch 范围查询关键字(gtltgtelte),用于 Neptune 后端。对于 Neo4j,_build_neo4j_fulltext_query graphiti_core/driver/neo4j/operations/search_ops.py:54-73 处理全文查询的构建,包括分组 ID 过滤。

实际示例

仅过滤活动(未过期)的边
from graphiti_core.search.search_filters import SearchFilters, DateFilter, ComparisonOperator

search_filter = SearchFilters(
    expired_at=[
        [DateFilter(date=None, comparison_operator=ComparisonOperator.is_null)]
    ]
)
过滤当前有效的边(时间点查询)
from graphiti_core.utils.datetime_utils import utc_now
now = utc_now()

search_filter = SearchFilters(
    valid_at=[
        [DateFilter(date=now, comparison_operator=ComparisonOperator.less_than_equal)]
    ],
    invalid_at=[
        [DateFilter(date=None, comparison_operator=ComparisonOperator.is_null)],
        [DateFilter(date=now, comparison_operator=ComparisonOperator.greater_than)]
    ]
)
将 SearchFilters 传递给搜索

SearchFilters 直接传递给 Graphiti.search_()

results = await graphiti.search_(
    query='Who is Tania',
    search_filter=search_filter,
)

search_filter 参数通过 search.py 中的 search() 函数 graphiti_core/search/search.py:103 向下传递,并通过 edge_search_filter_query_constructor graphiti_core/search/search_filters.py:120-123 等工具用于构建最终的数据库查询。

来源:tests/test_graphiti_int.py:63-75graphiti_core/search/search.py:98-108graphiti_core/search/search_utils.py:185-195