Asopitech With · RSS reader
RSS reader with Alopex DB
An RSS reader receives and shows new articles from site feeds. What would it look like built on Alopex DB?
Updated: Oct 12, 2026
What the service does
RSS is an XML format for syndicating web content. A channel has a title, a link and a description, and items sit beneath it. Each item has a title, link, synopsis, publication date, categories and an identifier that tells items apart. An RSS reader reads subscribed feeds on a schedule, collects new items and shows them.
Where the data lives
- SQL tables: subscribed feeds, items and read state live in tables. A unique constraint on the item identifier keeps the same item from being stored again.
- Full-text search: titles and synopses carry a full-text index for word search.
- Vectors: each item’s embedding sits in a vector column. Items from different sites about the same story land close together and are shown once. Items close to what the reader has already read move to the top.
The scheduler that visits the feeds is app code. The app fetches new items, creates their embeddings, and writes each item row and its vector together.
Deployment
Alopex DB is embedded in a desktop app or a command-line tool. Subscriptions and items are a single .alopex file. From the CLI, the reader can query their own articles in SQL.
Why Alopex DB fits
An RSS reader earns its place by picking the articles worth reading out of many. In Alopex DB, constraints that block duplicates, word search and closeness in meaning come together in one SQL query that decides the reading order.
See it in code
Articles live in a table with a unique guid, so duplicates are dropped and unread items are read newest-first. Just the core of handling a crawl.
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"])Duplicates are dropped with ON CONFLICT, so you can ingest freely and still read only the unread, newest first.
Alopex DB combines full-text and vector search in SQL, a natural fit for an RSS reader. The quickstart makes it easy to try.