- 搜索引擎
- 全文检索
- 后端
- 前端
- CLI
【免费下载链接】hister
Your own search engine
Hister 除了抓取网页外,还可以把本地文件变成可全文检索的知识库。这篇指南围绕 文件类型与索引文档 展开,覆盖indexer.directories目录索引的完整配置、PDF / DOCX / Markdown / Org / 纯文本五类文件的解析规则,以及hister import file的四种输入格式与--watch快照模式。读完你既能配置一个自动跟踪、自动过滤的本地目录索引,也能在服务端无法访问文件系统时,用命令行客户端把文件快照安全地导入 Hister。
本地文件索引:Hister 支持哪些格式
Hister 可以从两种途径索引本地文件:一种是配置indexer.directories后由服务端自动扫描与监视的「本地文档」(document.Local),另一种是通过hister import file显式导入的「远程文件文档」(document.RemoteFile)。两条路径共用同一套文件类型处理器。
五种受支持的本地文件类型
| 文件类型 | 扩展名 | 索引内容 | 标题来源 |
|---|---|---|---|
.pdf | 提取所有可读页面的纯文本 | 文件路径兜底 | |
| DOCX | .docx | 段落文本 | 优先 DOCX 元数据标题,否则文件路径兜底 |
| Markdown | .md,.markdown | 渲染后的 Markdown 文本 | 优先第一个 H1 标题,否则文件路径兜底 |
| Org mode | .org | 渲染后的 Org 文本 | 优先 OrgTITLE属性值,否则文件路径兜底 |
| 纯文本 | 任意合法 UTF-8 文本文件 | 完整文件内容 | 文件路径兜底 |
处理器列表与路由逻辑集中在 server/indexer/filetypes.go:fileTypeHandlers依次注册了pdfFileType、docxFileType、markdownFileType、orgFileType和plainTextFileType五个实现;fileTypeHandlerForPath按注册顺序匹配扩展名,没有任何专用处理器匹配时,一律回退到纯文本处理器(plainTextFileType.Match恒返回true)。
各处理器在Prepare阶段做三件事:解析文件字节、填充文档的Text/HTML/Title字段、写入type元数据。具体实现细节如下:
- PDF:server/indexer/pdf.go 调用
pdf.NewReader后通过GetPlainText()流式读出全部页面的纯文本;解析器内部 panic 会被recover捕获并转换为普通错误,避免单个损坏文件拖垮整个索引流程。提取不到任何文本时返回「pdf contains no extractable text」。 - DOCX:server/indexer/docx.go 使用 docxgo 打开文档,优先读取元数据标题;若元数据为空,再识别样式为
Title/Heading1的段落作为标题,最后兜底取第一个非空段落。段落文本以\n\n连接后进入索引。 - Markdown:server/indexer/markdown.go 用 gomarkdown 把源文件渲染为 HTML(
parser.CommonExtensions等标准扩展),渲染后的 HTML 存入d.HTML,再经sanitizer.SanitizeText清洗为纯文本用于全文检索;extractMarkdownTitle逐行扫描第一个#开头的 ATX 一级标题。 - Org mode:server/indexer/org.go 用 go-org 解析为 HTML,标题取自文档的
TITLE关键字(doc.Get("TITLE"))。 - 纯文本:先做
utf8.Valid校验,非法 UTF-8 一律返回ErrBinaryFile拒绝索引;合法内容整文件写入d.Text。
因此规则可以概括为:能匹配专用处理器就专用处理,否则只要是通过过滤规则的有效 UTF-8 文本文件就按纯文本索引,二进制文件直接跳过。如果只配置了目录而未声明filetypes,这条回退链会覆盖所有未被其他规则排除的文件。
标题与内容之外:文件如何成为文档
本地文件在索引时会被转成file://形式的 URL(见 files/files.go 的PathToFileURL),文档类型标记为document.Local。服务端在 server/indexer/files.go 的IndexFile中还会做一次幂等去重:如果同一 URL 已存在且Updated修改时间一致,就直接跳过重新提取,只有标签发生变化时才更新标签——这也是目录自动索引能高效处理海量文件的基础。
配置目录索引:自动扫描与实时监视
目录索引由indexer.directories配置项控制。配置完成后重启 Hister 服务端即可:服务端启动时会自动扫描该目录,随后通过 fsnotify 监视后续变化,无需为自动跟踪手动执行hister import file。
indexer: directories: - path: '~/Documents' label: 'documents' filetypes: ['pdf', 'docx', 'md', 'txt']path支持~/开头的主目录简写,files.ExpandHome会在运行时展开(files/files.go)。扫描与监视的实现分两层:
- 启动扫描:
Indexer.IndexAll/FileIndexQueue.EnqueueAll通过walkDirectoryFilesForUser递归遍历目录(server/indexer/files.go),逐文件应用过滤规则并回调IndexFile。 - 变更监视:files/watcher.go 基于 fsnotify 建立递归 watch,内置 200ms 去抖(
debounceTime);新增、修改、删除事件会进入FileIndexQueue,由后台队列线程分别执行IndexFile或DeleteFile。即使你改的是文件内容而非路径,队列也会用修改时间去重,避免重复提取。
值得一提的是,watcher默认跳过隐藏目录以及node_modules、bower_components、jspm_packages、__pycache__、__pypackages__这类依赖/缓存目录——它们的条目数量动辄上万,会迅速耗尽操作系统 watch 上限(见 files/files.go 的skipDirs定义)。
目录过滤规则:filetypes与其余规则如何共同生效
被监视目录上的filetypes是一个扩展名过滤器,配置时不要带前导点(如'md'而非'.md')。filetypes被省略时,Hister 会考虑所有通过其他目录规则的文件。
filetypes的匹配逻辑可以在 config/config.go 的Directory.IsMatching中看到:取文件扩展名去掉点后,与filetypes列表做大小写不敏感比对。除了扩展名过滤,以下目录规则仍会生效:
| 规则 | 行为 |
|---|---|
label | 给该目录索引出的每个文件附加同一个可检索标签 |
include_hidden | 默认跳过隐藏文件与隐藏目录,开启后才会包含 |
excludes | 匹配到的路径直接跳过 |
patterns | 设置后,只有匹配的文件才会被考虑 |
indexer.max_file_size_mb | 超过配置大小上限的文件被跳过 |
sensitive_content_patterns | 命中的文件被拒绝,除非索引路径显式允许敏感内容 |
关于过滤链的几个实现细节值得注意:
- 规则叠加顺序(
IsMatching):先判断隐藏文件,再判断excludes,然后判断filetypes扩展名,最后判断patterns;patterns一旦设置,只有命中任一 pattern 的文件才通过。 - 文件大小:
indexer.max_file_size_mb默认值为1 MB(见 config/config.go 的CreateDefaultConfig,MaxFileSize: 1)。超过限制的文件在IndexFile/prepareLocalFile中直接返回ErrFileTooLarge,空文件返回ErrEmptyFile。 - 敏感内容:默认配置自带 AWS 访问密钥、GitHub token、SSH / PGP 私钥等 6 组正则(
CreateDefaultConfig中的SensitiveContentPatterns)。命中检查在 server/document/document.go 的ProcessWithSensitivePatternContext中执行,命中即返回ErrSensitiveContent,除非文档设置了SkipSensitiveCheck(即「索引路径显式允许」)。 - 排除规则作用于父目录:
files.DirectoryMatchesPath会逐级检查根目录以下的每个父目录,因为被排除或隐藏的目录在遍历时会被整棵剪枝。
hister import file的四种导入格式
hister import file命令按扩展名分发到不同的导入路径(见 cmd/import_file.go 的importFile分支),支持以下格式:
| 文件类型 | 扩展名 | 行为 |
|---|---|---|
| Hister JSON 导出 | .json | 导入hister export之前写出的文档 |
| 7z 归档 | .7z | 导入压缩过的 Hister JSON 导出 |
| 保存的 HTML 页面 | .html,.htm | 存在时提取原始页面 URL |
| 本地文件快照 | 任意受支持的本地格式 | 本地提取内容并提交远程文件文档 |
判定细节:.json文件会先通过isHisterJSONExport探测是否为 Hister 导出结构,是则走 JSON 恢复流程,否则按普通文件快照处理;.html/.htm会尝试提取 canonical、OpenGraph 或 Twitter 的源 URL,提取不到则同样退化为快照。ZIP、gzip 等其他归档格式必须先解压再导入,纯文本必须为 UTF-8 编码——这两条限制会在导入报错信息中被明确提示(fileContentImportError)。
快照导入:文件字节永不上传
除 Hister JSON 导出、7z 和带源 URL 的 HTML 外,其余文件都被视为「本地文件快照」。内容提取发生在命令行客户端进程内,提取出的Text/HTML等文档字段通过/api/add提交给服务端,原始文件字节既不会发送到服务端,也不会被服务端保留。这与 导入文档 中「仅发送提取后的文档字段」的说明完全一致,也是快照模式适合「客户端能读到文件、服务端读不到」场景的根本原因——见 cmd/import_file.go 的prepareRemoteFile,它复用indexer.PrepareFileContent走与本地索引完全相同的 PDF / DOCX / Markdown / Org / 纯文本处理器。
快照文档的身份是remote-file://SOURCE/absolute/path(remoteFileURL构造),默认SOURCE为客户端主机名;建议用--source指定稳定名称,避免主机名变化或多个客户端路径相同时造成身份冲突:
hister import file --source alice-laptop ~/notes快照同样受indexer.max_file_size_mb大小限制与敏感内容检查约束。
导入目录与--watch持续跟踪
不提供任何输入路径时,hister import file会读取每一个已配置的监视目录并应用其全部过滤器,递归导入匹配文件,为这些目录创建远程文件快照。这专门用于命令行客户端可以访问、而服务端无法访问的目录:
# 无输入路径:导入所有已配置的监视目录 hister import file # 显式指定文件与目录 hister import file ~/notes ~/Documents/report.pdfexpandImportInputs会为每个输入去重(以绝对路径为键),并复用files.ShouldSkipDir与Directory.IsMatching,保证导入过滤与服务端目录索引行为一致。
加--watch后,命令在初始扫描完成后持续运行,跟踪新增与变更的快照,直到 Ctrl+C 或终止信号:
hister import file --watch --source alice-laptop ~/notes监视模式有几点明确行为(详见 导入文档):
- 只处理远程文件快照:初始扫描和后续监视都会跳过 Hister JSON 导出、7z 归档以及带源 URL 元数据的 HTML;普通 JSON 和无源 URL 的 HTML 仍受支持。
- 源文件删除不会删除已索引快照:即使启用了
delete_on_remove也不会删除;被重命名后发现的新路径会按新路径导入。 - 临时服务端故障会重试,提取或校验失败的文件在内容再次变化时会重新尝试;
--skip-existing只作用于初始扫描,之后的变更会覆盖已有快照。 --start-date/--end-date日期过滤不能与--watch组合使用。
两种文件索引方式的选择建议
综合本地文档与快照文档的区别,可以这样选择:
- 服务端能访问目录:首选
indexer.directories配置目录索引——服务端启动即扫描、fsnotify 实时监视、FileIndexQueue异步更新,无需任何手动命令,还附带CleanupLocalDocuments对已删除或不再匹配过滤规则的本地文档做索引清理。 - 服务端访问不到(如远程开发机、临时挂载点):用
hister import file [--watch]在客户端本地提取内容并提交快照,原始字节不外传,隐私与带宽都更可控。
无论哪种方式,五类格式的解析器、目录过滤规则(filetypes、excludes、patterns、include_hidden、max_file_size_mb、敏感内容检查)与大小/编码限制都是同一套实现,行为一致,迁移成本为零。
- 搜索引擎
- 全文检索
- 后端
- 前端
- CLI
【免费下载链接】hister
Your own search engine
相关推荐
Pwndbg调试会话录制格式:支持JSON与XML导出
Pwndbg调试会话录制格式:支持JSON与XML导出 调试会话录制是漏洞开发与逆向工程中的关键环节,能够帮助开发者复现问题、协作分析和存档关键操作。Pwndb
逆向工程调试器应用安全开发工具Quickwit 本地文件导入(Local Ingest)实战:使用 `quickwit tool local-ingest` 将 NDJSON 文件索引进 Schemaless 索引
Quickwit 本地文件导入(Local Ingest)实战:使用 quickwit tool local ingest 将 NDJSON 文件索引进 Sch
搜索引擎可观测性日志分析链路追踪后端全文检索游戏和软件频繁崩溃?Visual C++运行库AIO一站式解决方案
游戏和软件频繁崩溃?Visual C++运行库AIO一站式解决方案 你是否经常遇到游戏启动后立即闪退,专业软件报错"缺少MSVCP140.dll",或者应用程序
任务调度后端消息队列
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考