asopi tech
asopi techIndie Developer

Asopitech With · RSSリーダー

RSSリーダー with Alopex DB

RSSリーダーは、サイトの新しい記事をフィードで受け取って読むアプリです。これをAlopex DBで作り直すと…?

更新: 2026/10/12

どんなサービスか

RSSは、Webの内容を配信するためのXMLの形式です。チャンネルが、タイトル、リンク、説明を持ち、その下に記事が並びます。記事は、タイトル、リンク、概要、公開日時、カテゴリ、そして記事を見分ける識別子を持ちます。RSSリーダーは、購読したフィードを定期的に読み、新しい記事を集めて見せます。

データの置き場所

  • SQLテーブル:購読するフィード、記事、既読の状態をテーブルに持ちます。記事の識別子に一意の制約を付け、同じ記事を重ねて入れません。
  • 全文検索:タイトルと概要に全文検索の索引を張り、言葉で探します。
  • ベクトル:記事の埋め込みをベクトル列に持ちます。別のサイトが同じ話題を伝えた記事は、近いベクトルとしてまとめ、ひとつだけ見せます。読んだ記事に近い記事を、上に並べます。

フィードを巡回するスケジューラーは、アプリのコードです。アプリが新しい記事を取ってきて、埋め込みを作り、記事の行とベクトルを一緒に書き込みます。

配置の形

Alopex DBを、デスクトップのアプリやコマンドラインのツールに組み込みます。購読と記事は、ひとつの .alopex ファイルです。CLIからSQLで、自分の記事を調べることもできます。

Alopex DBが合う理由

RSSリーダーの価値は、たくさんの記事から、読む価値のある記事を選ぶところにあります。Alopex DBでは、制約による重複の防止、言葉の検索、意味の近さを、ひとつのSQLで組み合わせて、読む順を決めます。

コードで見る

記事をテーブルに持ち、guidを一意にして重複を防ぎ、未読を新しい順に読みます。巡回で集めた記事をさばく中心だけを取り出したコードです。

import alopex

# デスクトップやCLIに組み込む想定。購読と記事はひとつの .alopex ファイル
db = alopex.Database.open("rss.alopex")

# 記事を持つ。guid を一意にして、同じ記事を重ねて入れない
db.execute_sql("""
    CREATE TABLE IF NOT EXISTS items (
        guid TEXT UNIQUE,
        title TEXT,
        published DATE,
        read INTEGER
    )
""")

# 取得した記事を書き込む。重複は ON CONFLICT で捨てる
def ingest(guid, title, published):
    db.execute_sql(
        """
        INSERT INTO items (guid, title, published, read)
        VALUES (?, ?, ?, 0)
        ON CONFLICT (guid) DO NOTHING
        """,
        [guid, title, published],
    )

ingest("g1", "Rustの新機能", "2026-10-18")
ingest("g2", "Pythonの高速化", "2026-10-20")
ingest("g1", "Rustの新機能(再配信)", "2026-10-18")  # 重複 → 無視される

# 未読の記事を、新しい順に読む
rows = db.execute_sql("SELECT title, published FROM items WHERE read = 0 ORDER BY published DESC")
for row in rows:
    print(row["published"], row["title"])

同じ記事は ON CONFLICT で捨てるので、重複を気にせず取り込めます。未読だけを新しい順にたどれます。

全文検索とベクトル検索をSQLで組み合わせられるAlopex DBは、RSSリーダーにぴったりです。クイックスタートで手軽に試せます。

関連リンク