MongoDBエラーの解決方法:'$changeStream stage is only supported on replica sets'

intermediate🍃 MongoDB2026-04-26| MongoDB (バージョン 4.0から7.0)、Node.js/Python/Go ドライバー、および Docker ベースの開発環境。

Error Message

MongoServerError: The $changeStream stage is only supported on replica sets or sharded clusters
#mongodb#change-streams#レプリ

午前2時のログ・パニック洗練されたリアルタイム通知機能をデプロイしたばかりだとします。机上では、すべてが完璧に見えました。しかし、サービスがデータベースにアクセスした瞬間、ログにこのエラーが溢れ出します:

MongoServerError: The $changeStream stage is only supported on replica sets or sharded clusters

これは、ローカル環境やテストサーバーがおそらくスタンドアロンのMongoDBインスタンスを実行しているために発生します。スタンドアロン・インスタンスは多くのインストーラーでデフォルト設定されていますが、これらにはOplog(オペレーションログ)がありません。Change Streamsはデータのイベントをブロードキャストするために完全にOplogに依存しているため、これがないと動作しません。

クイックフィックス(TL;DR)スタンドアロンのMongoDBをシングルノードのレプリカセットに変換する必要があります。将来的に2台目のサーバーを追加する予定がなくても、MongoDBでChange Streamsを有効にするにはレプリケーション機構をアクティブにする必要があります。このプロセスは通常60秒以内に完了します。

  • --replSetフラグを付けてmongodプロセスを再起動します:mongod --replSet rs0- mongoshを開き、次を実行します:rs.initiate()## なぜこれが発生するのかmacOS (Homebrew)、Windows、Ubuntuでの標準的なインストールでは、MongoDBは単一の独立したプロセスとして起動します。これにより、Oplogの作成をスキップすることでディスク容量を約5%節約できます。しかし、Change StreamsはOplogを「テイル(末尾監視)」することで動作します。Oplogがなければ、ストリームも存在しません。レプリケーションをオンにすることで、すべての書き込み操作を非表示のコレクションに記録するようMongoDBに指示し、Change Streamがそれを監視できるようになります。

ローカルインストールの修正Dockerを使用せず、マシンに直接MongoDBをインストールした場合は、以下の手順に従ってください。

1. 設定の更新mongod.confファイルを開きます。Appleシリコン搭載のMacでHomebrewを使用した場合は、通常/opt/homebrew/etc/mongod.confにあります。Linuxの場合は/etc/mongod.confを確認してください。以下の2行を追加します:

replication:
  replSetName: "rs0"

2. データベースの再起動新しい設定を適用するために、サービスを再起動します。

# macOSユーザーの場合
brew services restart mongodb-community

# Linuxユーザーの場合
sudo systemctl restart mongod

3. レプリカセットの有効化mongoshと入力してMongoDBシェルに入ります。初期化コマンドを実行します:

rs.initiate()

3〜5秒待ちます。コマンドプロンプトがtest>からrs0 [direct: primary] test>に変わります。これで、シングルノードのレプリカセットが実行されました。

Docker Compose環境の修正mongo:latestのような標準のDockerイメージはスタンドアロンモードで起動します。開発ワークフローでこれを解決するには、初期化を自動的に処理するdocker-compose.yml設定を使用します。これにより、ボリュームを削除するたびに手動でrs.initiate()を実行する手間が省けます。

services:
  mongo:
    image: mongo:6.0
    command: ["--replSet", "rs0", "--bind_ip_all"]
    ports:
      - "27017:27017"
    healthcheck:
      test: "mongosh --eval 'rs.initiate()' || exit 0"
      interval: 10s
      timeout: 5s
      retries: 5

ヘルスチェック内の|| exit 0に注目してください。これにより、すでに初期化済みのデータベースに対してrs.initiate()が呼び出された場合に、コンテナーがエラーを報告するのを防ぎます。

修正の確認修正のテストは簡単です。watch.jsという名前のファイルを作成し、以下のNode.jsスニペットを貼り付けます:

const { MongoClient } = require('mongodb');

async function run() {
  const uri = 'mongodb://localhost:27017/?replicaSet=rs0';
  const client = new MongoClient(uri);
  await client.connect();
  
  console.log('Connected. Watching testdb.orders...');
  const stream = client.db('testdb').collection('orders').watch();

  stream.on('change', (change) => {
    console.log('Event detected:', change.operationType, change.fullDocument);
  });
}

run().catch(console.error);

node watch.jsを実行します。GUIまたはシェルを使用して、ordersコレクションにドキュメントを挿入します。ターミナルにイベントが表示されれば、エラーは正式に解決されました。

ベストプラクティスとパフォーマンス本番環境に移行する前に、2つの点に注意してください。まず、アプリケーションの接続文字列を更新します。ドライバーがセットに正しく接続する方法を認識できるように、replicaSet=rs0パラメータを含める必要があります。次に、ディスク容量を監視してください。Oplogは「キャップ付き(Capped)」コレクションです。際限なく増え続けることはありませんが、ストレージの事前割り当てが必要です。トラフィックの多いアプリでは、一時的なネットワークの瞬断中に変更を見失わないよう、10GBから50GBのOplogを確保するのが一般的です。

関連資料- MongoDB Change Streams 公式ドキュメント- スタンドアロンからレプリカセットへの変換の詳細

Related Error Notes