asopi tech
asopi techIndie Developer

Asopitech With · ノートアプリ

Obsidian with Alopex DB

Obsidianは、端末に保存したノートをリンクでつなぐノートアプリです。これをAlopex DBを使って再現すると…?

更新: 2026/10/12

どんなサービスか

Obsidianは、ノートを端末に保存し、オフラインでもすぐに開けるノートアプリです。ノートどうしをリンクでつなぎ、つながりをグラフで見せます。扱うデータは、ノートの本文、ノートの間のリンク、タグです。

データの置き場所

  • SQLテーブル:ノート、リンク、タグをテーブルに持ちます。あるノートを指しているノートの一覧は、リンクのテーブルから引きます。
  • 全文検索:本文に全文検索の索引を張り、言葉そのもので探します。
  • ベクトル:段落ごとの埋め込みをベクトル列に持ち、言葉が違っても意味の近いノートを探します。

埋め込みはアプリが作り、ノートの保存と同じトランザクションで書き込みます。

配置の形

Alopex DBを、デスクトップと端末のアプリに組み込みます。保管庫ごとに1つの .alopex ファイルを持ち、サーバーは要りません。保管庫を別の端末に移すときは、ファイルをコピーします。

Alopex DBが合う理由

ノートは、手元で速く開けることがいちばん大事です。Alopex DBは、リンクのテーブル、全文検索、意味検索を1つのファイルの中で組み合わせます。ノートの検索と、つながりの表示が、同じSQLでそろいます。

コードで見る

ノートとリンクをテーブルに持ち、あるノートを指すノート(バックリンク)をSQLで引きます。つながりをたどる中心だけを取り出したコードです。

import alopex

# 保管庫ごとに1つの .alopex ファイル
db = alopex.Database.open("obsidian.alopex")

# ノートとリンクを持つ
db.execute_sql("""
    CREATE TABLE IF NOT EXISTS notes (
        id INTEGER PRIMARY KEY,
        title TEXT,
        body TEXT
    )
""")
db.execute_sql("""
    CREATE TABLE IF NOT EXISTS links (
        src_id INTEGER,
        dst_id INTEGER
    )
""")

notes = [(1, "MOC", "入口のノート"), (2, "Rust", "所有権のメモ"), (3, "WASM", "RustからWASM")]
for n in notes:
    db.execute_sql("INSERT INTO notes (id, title, body) VALUES (?, ?, ?)", list(n))
for src, dst in [(1, 2), (1, 3), (3, 2)]:  # MOC→Rust, MOC→WASM, WASM→Rust
    db.execute_sql("INSERT INTO links (src_id, dst_id) VALUES (?, ?)", [src, dst])

# 「Rust」を指しているノート(バックリンク)を引く
rows = db.execute_sql("""
    SELECT s.title
    FROM links AS l
    JOIN notes AS s ON s.id = l.src_id
    JOIN notes AS d ON d.id = l.dst_id
    WHERE d.title = ?
    ORDER BY s.title
""", ["Rust"])

for row in rows:
    print("backlink:", row["title"])

リンクのテーブルを逆からたどると、バックリンクになります。つながりの表示が、同じSQLでそろいます。

リンクのテーブル、全文検索、意味検索を一つのファイルで扱えるAlopex DBで、自分の保管庫を作ってみよう。入口はクイックスタートです。

関連リンク