Asopitech With · コミュニティサイト
Reddit コミュニティと投票 with Alopex DB
Redditは、たくさんのコミュニティで投稿とコメントを交わし、投票で表示を決めるコミュニティサイトです。これをAlopex DBで作り直すと…?
更新: 2026/10/13
どんなサービスか
Redditには、ニュース、スポーツ、テレビ、動物など、たくさんのコミュニティがあります。投稿とコメントには賛成と反対の投票ができ、投票がコミュニティで何を上位に出すかを決めます。受けた投票は、利用者のカルマにも反映されます。今回作り直すのは、コミュニティ、投稿、投票の部分です。
データの置き場所
- Alopex DBのSQLテーブル:コミュニティ、利用者、投稿、コメント、投票をSQLテーブルに持ちます。
- SQL:投票の集計と並べ替え、カルマの集計を、SQLの集計で出します。
- 全文検索とベクトル検索:投稿の本文を全文検索で探し、投稿の埋め込みのベクトルで似た投稿を探します。
投稿の埋め込みのベクトルを作るのは、サービスのコードです。
配置の形
サービスの側で、Alopex DBをクラスタとして動かします。たくさんの利用者からの投稿と投票は、ノードを足して受けます。
Alopex DBが合う理由
コミュニティのデータは、投稿、コメント、投票の関係と、その集計です。Alopex DBは、その関係をSQLで持ち、全文検索とベクトル検索を同じエンジンで行います。
コードで見る
コミュニティ・投稿・投票をテーブルに持ち、投票をSQLの集計でスコアにして並べます。表示順の中心だけを取り出したコードです。
import alopex
# サービス側で Alopex DB を動かす想定
db = alopex.Database.open("reddit.alopex")
# コミュニティ・投稿・投票を SQL テーブルで持つ
db.execute_sql("""
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY,
community TEXT,
author TEXT,
title TEXT
)
""")
db.execute_sql("""
CREATE TABLE IF NOT EXISTS votes (
post_id INTEGER,
voter TEXT,
value INTEGER
)
""")
# 投稿と投票を書き込む
db.execute_sql("INSERT INTO posts (id, community, author, title) VALUES (?, ?, ?, ?)", [1, "cats", "alice", "うちの猫"])
db.execute_sql("INSERT INTO posts (id, community, author, title) VALUES (?, ?, ?, ?)", [2, "cats", "bob", "猫の爪とぎ"])
for post_id, voter, value in [(1, "bob", 1), (1, "carol", 1), (2, "alice", 1), (2, "carol", -1)]:
db.execute_sql("INSERT INTO votes (post_id, voter, value) VALUES (?, ?, ?)", [post_id, voter, value])
# 投票を集計し、スコアの高い順に並べる(コミュニティの表示順)
rows = db.execute_sql("""
SELECT p.title, SUM(v.value) AS score
FROM posts AS p
JOIN votes AS v ON v.post_id = p.id
WHERE p.community = ?
GROUP BY p.id, p.title
ORDER BY score DESC
""", ["cats"])
for row in rows:
print(row["score"], row["title"])投票を足し合わせてスコアにし、高い順に並べます。表示の順番は、SQLの集計そのものです。
投票の集計と似た投稿の検索を同じエンジンでこなせるAlopex DBで、コミュニティを作ってみよう。