AI

OSSドキュメントDB比較:MongoDB vs CouchDB vs SurrealDB でドキュメントDBを選ぶ

オープンソースラボ編集部2026年6月14日

OSSドキュメントDB比較:MongoDB vs CouchDB vs SurrealDB でドキュメントDBを選ぶ

MySQLやPostgreSQLのようなリレーショナルDBでは扱いにくい可変スキーマ・ネストしたドキュメント・JSONデータの管理には、ドキュメント指向NoSQLデータベースが適しています。MongoDB(世界最大シェアNoSQL)・CouchDB(Apache製・マルチマスターレプリケーション)・SurrealDB(多モデル・GraphQL・リアルタイム・次世代)の3つが2026年のOSSドキュメントDB主要選択肢です。

ドキュメントDBを使う理由

  • 可変スキーマ: ユーザーごとに異なる属性・プロパティ(SNSプロフィール・商品カタログ)をスキーマなしで格納
  • JSONネイティブ: フロントエンドとバックエンド間のJSONデータを変換なしに保存・取得
  • 水平スケール: リレーショナルDBのような複雑なJOINなしにシャーディングで水平スケール
  • 組み込み配列: タグ・コメント・関連ID等の配列をカラムなしにドキュメント内に格納

主要ツールの概要

MongoDB

2009年公開(MongoDB Inc.)、C++製のOSSです。GitHubスター26k+。世界最大シェアNoSQLドキュメントDBで、SSPL v1ライセンスです。BSONドキュメント・インデックス・Aggregation Pipeline・Change Streams・Atlas Search(全文検索)・マルチドキュメントトランザクションが統合されています。

# docker-compose.yml: MongoDB 7 + mongo-express
version: "3.8"
services:
  mongodb:
    image: mongo:7
    restart: unless-stopped
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASS}
    volumes:
      - mongo_data:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/init.js:ro
    command: --wiredTigerCacheSizeGB 0.5  # メモリ制限(512MB)

  mongo-express:
    image: mongo-express:latest
    restart: unless-stopped
    ports:
      - "8081:8081"
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: admin
      ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_PASS}
      ME_CONFIG_MONGODB_URL: mongodb://admin:${MONGO_PASS}@mongodb:27017/
      ME_CONFIG_BASICAUTH_USERNAME: meadmin
      ME_CONFIG_BASICAUTH_PASSWORD: ${ME_PASS}

volumes:
  mongo_data:
# Python: PyMongo でドキュメントCRUD・Aggregation Pipeline
from pymongo import MongoClient, ASCENDING, DESCENDING
from datetime import datetime, timedelta
from typing import Optional

client = MongoClient('mongodb://admin:password@localhost:27017/')
db = client['myapp']
articles = db['articles']

def create_article(title: str, content: str, tags: list, author_id: str) -> dict:
    '''記事ドキュメントをMongoDBに作成'''
    doc = {
        'title': title,
        'content': content,
        'tags': tags,
        'author_id': author_id,
        'stats': {'views': 0, 'likes': 0},
        'metadata': {'created_at': datetime.utcnow(), 'updated_at': datetime.utcnow()},
        'published': False,
    }
    result = articles.insert_one(doc)
    return {'id': str(result.inserted_id), **doc}

def search_articles_by_tag(tag: str, limit: int = 20) -> list:
    '''タグで記事を検索(配列フィールドへの$inクエリ)'''
    cursor = articles.find(
        {'tags': {'$in': [tag]}, 'published': True},
        projection={'content': 0}  # contentを除外(軽量化)
    ).sort('metadata.created_at', DESCENDING).limit(limit)
    return list(cursor)

def get_tag_ranking(days: int = 30) -> list:
    '''過去N日間で最もよく使われたタグランキング(Aggregation Pipeline)'''
    since = datetime.utcnow() - timedelta(days=days)
    pipeline = [
        {'$match': {'metadata.created_at': {'$gte': since}, 'published': True}},
        {'$unwind': '$tags'},  # 配列を展開
        {'$group': {'_id': '$tags', 'count': {'$sum': 1}, 'total_views': {'$sum': '$stats.views'}}},
        {'$sort': {'count': DESCENDING}},
        {'$limit': 20},
        {'$project': {'tag': '$_id', 'count': 1, 'total_views': 1, '_id': 0}},
    ]
    return list(articles.aggregate(pipeline))

# インデックス作成(パフォーマンス最適化)
articles.create_index([('tags', ASCENDING)])
articles.create_index([('metadata.created_at', DESCENDING)])
articles.create_index([('title', 'text'), ('content', 'text')])  # 全文検索インデックス

CouchDB

2005年公開(Apache Software Foundation)、Erlang製のOSSです。GitHubスター6k+。HTTPレストフルAPIで操作できるApache製ドキュメントDBで、マルチマスターレプリケーション(CouchDB Sync Protocol)が特徴です。オフラインファーストのアプリケーション開発(PouchDB→CouchDB同期)やIoTデバイスからのデータ収集に適しています。

# docker-compose.yml: CouchDB 3
version: "3.8"
services:
  couchdb:
    image: couchdb:3
    restart: unless-stopped
    ports:
      - "5984:5984"
    environment:
      COUCHDB_USER: admin
      COUCHDB_PASSWORD: ${COUCH_PASS}
    volumes:
      - couchdb_data:/opt/couchdb/data

volumes:
  couchdb_data:
# Python: CouchDB HTTP REST API でドキュメント操作
import requests

COUCH_URL = 'http://admin:password@localhost:5984'

def create_database(db_name: str) -> dict:
    '''CouchDBデータベース作成(PUT /db_name)'''
    return requests.put(f'{COUCH_URL}/{db_name}').json()

def save_document(db_name: str, doc: dict, doc_id: Optional[str] = None) -> dict:
    '''CouchDBにドキュメントを保存(PUT or POST)'''
    if doc_id:
        resp = requests.put(f'{COUCH_URL}/{db_name}/{doc_id}', json=doc)
    else:
        resp = requests.post(f'{COUCH_URL}/{db_name}', json=doc)
    return resp.json()

def query_by_view(db_name: str, view_name: str, key: str = None) -> list:
    '''CouchDBのViewクエリで集計データを取得'''
    url = f'{COUCH_URL}/{db_name}/_design/mydesign/_view/{view_name}'
    params = {'key': f'"{key}"'} if key else {}
    resp = requests.get(url, params=params)
    return resp.json().get('rows', [])

SurrealDB

2022年公開(Surreal)、Rust製のOSSです。GitHubスター28k+。SQL・GraphQL・ドキュメント・グラフ・時系列を1つのデータベースで扱える次世代多モデルDBで、WebSocketによるリアルタイムクエリ・Row-levelセキュリティ・埋め込みJavaScript関数・WASM等の機能を持ちます。

# docker-compose.yml: SurrealDB
version: "3.8"
services:
  surrealdb:
    image: surrealdb/surrealdb:latest
    restart: unless-stopped
    ports:
      - "8000:8000"
    command: start --log trace --user root --pass ${SURREAL_PASS} file:/mydata/mydb.db
    volumes:
      - surreal_data:/mydata

volumes:
  surreal_data:
# Python: SurrealDB SDK でSurrealQLクエリ
from surrealdb import Surreal

async def surreal_demo():
    async with Surreal('ws://localhost:8000/rpc') as db:
        await db.signin({'user': 'root', 'pass': 'password'})
        await db.use('myapp', 'mydb')

        # レコード作成(ULIDが自動生成)
        person = await db.create('person', {
            'name': '山田太郎',
            'email': 'taro@example.com',
            'tags': ['developer', 'oss'],
        })

        # SurrealQL: JOINなしでグラフリレーション
        await db.query('RELATE person:taro->follows->person:hanako')

        # グラフトラバーサル(フォロー関係を2ホップで取得)
        result = await db.query(
            'SELECT ->follows->person.name AS following FROM person:taro FETCH following'
        )
        return result

機能比較表

比較項目MongoDBCouchDBSurrealDB
トランザクション✅ マルチドキュメント
グラフDBサポート✅ ネイティブ
オフライン同期✅ Sync Protocol
リアルタイムChange StreamsChanges Feed✅ WebSocket
GitHub Stars26k+6k+28k+

ドキュメントDBはDevOpsカテゴリ/categories/devopsの監視スタック(Prometheus/Grafana)と組み合わせてMongoDBのスロークエリ・インデックス使用率・WiredTigerキャッシュヒット率をメトリクスとして収集します。LLMツールカテゴリ/categories/llm-toolsのベクトルストア(pgvector/Chroma)とSurrealDBの多モデル特性を組み合わせてドキュメント・ベクトル・グラフを1つのDBでRAGパイプラインに活用します。

FAQ

Q. MongoDBのAggregation Pipelineで複雑な集計を実装するには?

A. $match$group$project$sortの順でパイプラインを構築します。典型的なパターン: 時間別売上集計: $match(期間フィルタ)→$group: {_id: {$dateToString: {format: '%Y-%m-%d', date: '$created_at'}}, revenue: {$sum: '$amount'}}$sort: {_id: 1}。ルックアップ(JOIN代替): $lookup: {from: 'users', localField: 'user_id', foreignField: '_id', as: 'user'}$unwind: '$user'$project: {'user.name': 1, revenue: 1}。ウィンドウ関数: $setWindowFieldsで累計売上・移動平均を計算(MongoDB 5.0+)。Explain: .explain('executionStats')でパイプラインの実行計画・COLLSCAN→IXSCANを確認してインデックスを最適化。

Q. CouchDBとPouchDBを使ったオフラインファーストアプリの実装方法は?

A. PouchDB(ブラウザ内DB)とCouchDBのSync Protocolを使って、オフライン状態でもデータ保存・オンライン復帰時に自動同期するアプリを構築できます。実装: ①npm install pouchdb pouchdb-find②ブラウザ側: const localDB = new PouchDB('myapp')localDB.put({_id: 'doc-1', data: 'value'})でオフラインに書き込み③同期開始: localDB.sync('https://admin:pass@couchdb.example.com/myapp', {live: true, retry: true})→オンライン時に自動でCouchDBに同期④競合解決: CouchDBの_conflictsフィールドで競合を検出→ビジネスロジックで最新バージョンを選択。ユースケース: フィールドワーカー向けアプリ(電波が届かない場所でのデータ収集→事務所でPCをWiに繋いだ瞬間に自動同期)。

Q. SurrealDBでグラフリレーションを使ったソーシャルグラフを構築するには?

A. SurrealQLのRELATE文でグラフエッジを作成してJOINなしにグラフトラバーサルクエリを実行できます。フォロー関係: RELATE person:taro->follows->person:hanako SET created_at = time::now()でエッジ作成→SELECT ->follows.name FROM person:taroでフォロー中のユーザー名を取得。友達の友達(2ホップ): SELECT ->follows->follows.name AS friends_of_friends FROM person:taro WHERE ->follows->follows != person:taro。共通フォロワー: LET $a = (SELECT ->follows FROM person:taro).follows; LET $b = (SELECT ->follows FROM person:hanako).follows; SELECT * FROM $a INTERSECT $b。アクティビティフィード: SELECT in.*, out.title AS article_title FROM liked WHERE out.published = true ORDER BY created_at DESC LIMIT 20でフォロー中ユーザーのいいね活動をフィードとして取得。

Q. MongoDB・CouchDB・SurrealDBをどう使い分けるべきですか?

A. 大規模Webアプリ・豊富なエコシステム・Aggregation分析にはMongoDBオフライン同期・HTTPファーストAPI・IoTデータ収集にはCouchDBグラフ+ドキュメント+SQL統合・リアルタイム・新規プロジェクトにはSurrealDBが向いています。MongoDB優位: ①世界最大シェア→ドキュメント・サポート・ライブラリが豊富②Aggregation Pipelineで複雑な分析→BI/レポーティングに最適③Atlas(マネージド)への移行が容易→セルフホスト→クラウド移行に備えた構成が取りやすい④MongoDBのAtlas Searchで全文検索統合(Lucene/kNN)。CouchDB優位: ①HTTP REST APIがネイティブ→curlで直接操作②PouchDBとの同期で最高のオフラインファースト対応③マルチマスターレプリケーション→複数拠点への分散が容易。SurrealDB優位: ①SQL・GraphQL・ドキュメント・グラフを1DBで統合→マイクロサービスのDB数を削減②Row-levelセキュリティ→APIサーバーをバイパスしてフロントエンドから直接クエリできる③Rustベースで高速・低メモリ消費。

まとめ

ユースケース推奨ツール
大規模・エコシステム・Aggregation分析MongoDB
オフライン同期・HTTP API・IoTCouchDB
多モデル・グラフ・リアルタイム・新規SurrealDB

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。