← 返回目录

第 4 卷

第 4 / 6 卷日期:

11--- filterEvents:结构事件(turn/*)不在语义文档里---
12命中0条(turn/start不产生搜索文档,所以是0)
13--- filterEvents:text过滤兜底FTS搜不到的中文子串---
14FTS搜「落盘」:命中0个会话
15text过滤搜「落盘」:命中1条(返回文档数组:没有snippet,也不分页)
16·seq11 user/message:日志怎么落盘?
17--- filterEvents:text匹配时按空白切段---
18·seq12 assistant/message:顺序是:先写内存的⏎events,再flush到磁盘。
19搜索词按空白切成两段、段间用\s+连,所以原文里两段之间隔着换行也能命中;
20而*、?、(这些正则特殊字符会被转义,在你手里永远是字面量。

text 子句:FTS 搜不到时的兜底。前面几个都按元数据圈定,只有它按内容找——所以它也用不了 values(那是候选值列表),改用 text 装要匹配的那段内容。上一节那个搜不到

的“落盘”,用它就捞得出来:

复制代码

1awaitctx.sessionQuery.searchSessions({query:'落盘'})//命中0个会话
2awaitctx.sessionQuery.filterEvents(SessionId('sess-grandchild'), [
3{kind:'text',text:'落盘'},
4])

它做的是逐条扫描:搜索词按空白切成几段,每段都按字面文本处理(源码里 compileSessionTextFilter 把它编译成正则,但元字符会被转义——你输 .* 搜到的就

是这两个字符),段之间允许任意空白,不区分大小写。所以它搜的是字面子串:中文子串、英文半个词都能搜到。代价是没有索引,一次要扫一份日志,慢。

返回的是文档数组,不分页、按 seq 升序,和全文搜索“按相关性 + 游标翻页”正好相反。

到这里,“怎么搜”这一问就齐了:按内容搜(全文搜索),按条件筛(精确过滤)。下一节换第三问:怎么追。

谱系的数据基础是 header 里的 parentSession:第 9 讲聊 fork 时提过,它记的是“从哪个会话分出来的”,只在 fork 时写下。每个子会话各记一条,把这些散在各处的 parent 拼起

来,就是一张谱系。追的时候分两个方向:

往上:搜到有用的记录后,想知道它是从哪次会话分出来的(典型流程就是先搜、再追)

往下:精确过滤的 parent 过滤器能“只看 fork 自这个会话的那些”,靠的就是谱系数据。

追这类关系的同样是 ctx.sessionQuery 上的 traceSession(id)。跑 npm run start:ch11:lineage,先造一条 root → child → grandchild 的谱系,再查:

复制代码 1--- 追踪 sess-grandchild 的谱系 ---

2目标:sess-grandchild 3完整:true

4祖先(由近及远):

5· sess-child 6· sess-root

7--- 追踪 sess-root 的后代 --- 8目标:sess-root

9后代树:

10· sess-child 11· sess-grandchild

traceSession() 一次读出目标往上、往下两个方向:

往上:ancestors,一条线,从直接父级往外排(追 sess-grandchild 得到 sesschild → sess-root),第一个是最亲的父级,最后一个是最远的祖先。

往下:descendants,一棵树,每一项是一个从直接子级开始的节点,节点里又带一层自己的 descendants,一层套一层(追 sess-root 得到 sess-child,它下面又套着

sess-grandchild)。同一层的兄弟按创建时间排,时间相同再按 id 排。

图 12-1
图 12-1

形状不同,是因为 parentSession 是单向的:它只写在子会话的 header 里、指向父级,没有反过来的“子”字段。往上是顺着它一跳一跳(成链);往下得先把整个语料库扫一遍、按

它归成“父 → 子们”再展开(成树)。

不过祖先这条链不一定追得到顶。返回结果里还带一个 complete:目标、ancestors、 descendants 每次都在,此外只再带两个字段里的一个,带 root 还是

unresolvedParentId,由 complete 决定。

complete附带字段含义

祖先链一路追到了顶;root 是链顶那条记录(目标自己 TRUEroot 就是根时,root 就是目标)

链断了——某个父级不在当前语料库里(比如父会话是 FALSEunresolvedParentId从另一个工作区 fork 来的,这个查询引擎没看见

它),unresolvedParentId 是第一个追不到的那个

全站分卷索引 · 6 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷