返回市场
黑曜石索引服务

黑曜石索引服务

作者:pmmvr5 星标更新:2025-03-23

项目介绍

Obsidian 索引服务

此服务监控 Obsidian 保险库目录,并将 Markdown 文件的元数据及全文内容索引到一个 SQLite 数据库中。我最初是为我的 mcp-server 项目构建了它,但后来改用了一个使用 Obsidian 插件 API 的实现。尽管如此,我认为这个服务仍然可以作为一个无偏见的笔记索引器或同步工具(参见“未来步骤”下的注释),因此我将其发布在这里。

功能

它跟踪 Obsidian 保险库中的文件更改(创建、修改、删除)并将所有信息存储在 SQLite 中,可通过 Docker 卷访问。它捕获以下内容:

  • 路径:文件路径(唯一标识符)
  • 标题:来自文件名
  • 父文件夹:相对于保险库根目录
  • 标签:来自 YAML 前置元数据
  • 创建日期:文件系统时间戳
  • 修改日期:文件系统时间戳
  • 内容:笔记全文
  • 状态:处理结果(成功/错误)
  • 错误消息:如果处理失败,则提供详细信息

安装与使用

需求

  • Python 3.12 或更高版本
  • Docker 和 Docker Compose(用于容器化使用)
  • uv(可选,但推荐)

安装

  1. 克隆仓库:

     git clone https://github.com/pmmvr/obsidian-index-service.git
     cd obsidian-index-service
    
  2. 设置虚拟环境:

    • 使用 uv(推荐):

      uv venv
      source .venv/bin/activate # Linux/macOS
      .venv\Scripts\activate # Windows
      
    • 使用 python(标准方法):

      python -m venv .venv
      source .venv/bin/activate  # Linux/macOS
      .venv\Scripts\activate     # Windows
      
  3. 安装依赖项:

    • 使用 uv(推荐):
      uv sync  # 从 uv.lock 安装
      uv pip install pytest pytest-bdd pytest-mock  # 用于测试
      
    • 使用 pip
      pip install -e .
      pip install pytest pytest-bdd pytest-mock  用于测试
      

本地运行

设置环境变量:

export OBSIDIAN_VAULT_PATH=/path/to/vault
export DB_PATH=/path/to/notes.sqlite

运行:

python main.py

使用 uv

uv run python main.py

一次性扫描:

python main.py --scan-only

或者使用 uv

uv run python main.py --scan-only

命令行选项

  • --vault-path:保险库目录路径
  • --db-path:SQLite 数据库路径
  • --scan-only:仅扫描而不监视

使用 Docker

  1. 构建并运行:
    docker-compose up -d
    
  2. 它挂载你的保险库并暴露 SQLite 数据库。

其他服务的只读访问

允许其他服务读取数据库(例如,用于扫描更改):

  1. 在你的 docker-compose.yml 中使用与 obsidian-index-service 相同的卷:
    services:
      your-service:
        image: your-image
        volumes:
          - ${DB_VOLUME_PATH:-./data}:/data:ro  # 只读挂载
    
  2. Obsidian Index Service 写入 /data/notes.sqlite(挂载为读写),而其他服务(如 mcp-server)读取它。SQLite 的 WAL 模式处理并发访问。

工作原理

Obsidian 索引服务通过以下过程运行:

  1. 启动 (ObsidianIndexService.__init__)

    • 从环境变量或命令行参数加载配置
    • 初始化数据库连接 (DatabaseConnection)
    • 设置笔记处理器 (NoteProcessor)
    • 建立信号处理器以优雅地关闭
  2. 数据库初始化 (DatabaseConnection.__init__)

    • 创建/连接到 SQLite 数据库
    • 将数据库设置为 WAL(预写日志)模式以提高并发性
    • 如果不存在,则创建带有路径、标题、标签等列的 'notes' 表
  3. 初始保险库扫描 (NoteProcessor.scan_vault)

    • 查找保险库目录中的所有 Markdown 文件(*.md, *.markdown)
    • 对于每个文件,提取元数据
    • 将所有提取的元数据添加到数据库 (NoteOperations.insert_note)
  4. 持续监控 (FileWatcher.watch)

    • 监视保险库目录中的文件系统事件
    • 处理不同类型的事件:
      • 文件创建:索引新文件
      • 文件修改:更新已更改文件的索引
      • 文件删除:从索引中移除条目
      • 文件移动/重命名:更新路径信息
  5. 文件处理 (NoteProcessor.process_note)

    • 从 Markdown 文件中提取元数据
    • 包括路径、标题、父文件夹、标签、创建/修改日期
    • 使用这些信息更新数据库 (NoteOperations.upsert_note)
  6. 优雅关闭 (ObsidianIndexService.shutdown)

    • 接收到终止信号时正确关闭文件监视器和数据库连接

该服务在后台运行,持续使 SQLite 数据库与 Obsidian 保险库保持同步。其他应用程序可以使用此数据库来访问笔记元数据,而无需直接解析 Markdown 文件。

开发

运行测试:

pytest

项目状态

  • 已完成:核心索引(元数据+内容)、Docker 设置、文件监视、数据库 CRUD 操作。
  • 下一步:计划了一个 API,但最终选择了插件方法。

未来步骤(同步工具潜力)

经过一些重构,我可以将其视为一个同步工具:

  • 远程后端:添加对云存储(例如 Dropbox)或服务器的支持。
  • 同步逻辑:推送本地更改(内容+元数据)到远程,拉取远程更新,处理冲突(例如,最后写入者获胜)。
  • 数据库调整:添加 sync_statusremote_id 列。
  • 文件监视器更新:排队更改以进行同步,而不仅仅是索引。
  • CLI 选项:添加 --sync 以手动或连续触发同步。
  • 错误处理:在网络失败时重试,记录问题。