シナリオベースおよび問題解決型の質問
「orders」というコレクションがあり、数百万件のドキュメントが含まれています。各注文には「status」フィールド(例:「pending」、「shipped」、「delivered」)と「timestamp」フィールドがあります。過去 24 時間のすべての「pending」注文を効率的に見つけるにはどうすればよいですか?
回答:
{ status: 1, timestamp: -1 } に複合インデックスを作成します。次に、db.orders.find({ status: 'pending', timestamp: { $gte: ISODate('...') } }) を使用してクエリを実行します。このインデックスにより、ステータスによる効率的なフィルタリングとタイムスタンプでの範囲スキャンが可能になります。
アプリケーションでは、「username」と「email」でユーザープロファイルを頻繁に取得する必要があります。両方の検索タイプを効率的にサポートするために、どのようにインデックスを設計しますか?
回答:
2 つの個別の単一フィールドインデックスを作成します:db.users.createIndex({ username: 1 }) と db.users.createIndex({ email: 1 })。これにより、MongoDB はどちらかのフィールドに基づくクエリに対して適切なインデックスを使用できます。
「products」という名前のコレクションには、「price」フィールドがあります。特定の価格範囲内の製品を見つけ、それらを「name」で並べ替える必要があります。このクエリを最適化するにはどうすればよいですか?
回答:
{ price: 1, name: 1 } に複合インデックスを作成します。クエリは db.products.find({ price: { $gte: 10, $lte: 50 } }).sort({ name: 1 }) となります。このインデックスは、価格の範囲クエリと名前のソート操作の両方をサポートします。
ソーシャルメディアアプリケーションを設計しています。ユーザーは多くの「posts」を持つことができます。投稿をユーザーのドキュメント内に埋め込むべきですか、それとも参照を持つ別の「posts」コレクションを使用すべきですか?選択の根拠を説明してください。
回答:
参照を持つ別の「posts」コレクションを使用します。埋め込みは、大きくなり続けるユーザー ドキュメントにつながり、16MB の BSON 制限を超え、頻繁な更新でパフォーマンスの問題を引き起こします。参照を使用すると、スケーラブルな成長と投稿の効率的なクエリが独立して可能になります。
アプリケーションで「logs」コレクションからのデータ集計時にクエリが遅くなる問題が発生しています。集計パイプラインには $match、$group、$sort が含まれています。パフォーマンスを診断し改善するために、どのような手順を踏みますか?
回答:
まず、集計パイプラインで explain() を使用してボトルネックを特定します。$match および $sort ステージで使用されるフィールドに適切なインデックスが存在することを確認します。可能な場合はカバークエリの使用を検討するか、頻繁にアクセスされるレポートのためにデータを事前集計します。
ユーザーセッションを保存する必要があり、非アクティブ状態が 30 分続くと期限切れになります。MongoDB でこれを効率的に実装するにはどうすればよいですか?
回答:
「sessions」コレクションのタイムスタンプフィールド(例:lastActivity)に TTL(Time-To-Live)インデックスを使用します。db.sessions.createIndex({ lastActivity: 1 }, { expireAfterSeconds: 1800 }) でインデックスを作成します。MongoDB は 30 分以上前のドキュメントを自動的に削除します。
アプリケーションでは、ドキュメントに対するアトミックな更新を実行し、カウンターをインクリメントして配列にアイテムを追加する必要があります。データの整合性をどのように保証しますか?
回答:
$inc および $push オペレーターを使用した単一の db.collection.updateOne() 操作を使用します。MongoDB は単一ドキュメント書き込みのアトミック性を保証します。例:db.products.updateOne({ _id: productId }, { $inc: { stock: -1 }, $push: { buyers: userId } })。
「events」コレクションには「location」フィールドがあり、これは座標の配列 [longitude, latitude] です。指定されたポイントから 5km 以内のすべてのイベントを見つけるにはどうすればよいですか?
回答:
「location」フィールドに 2dsphere インデックスを作成します:db.events.createIndex({ location: '2dsphere' })。次に、クエリに $centerSphere を使用した $geoWithin オペレーターを使用します:db.events.find({ location: { $geoWithin: { $centerSphere: [[lon, lat], radiusInRadians] } } })。
リレーショナルデータベースから MongoDB へのデータ移行を行っています。「customers」テーブルと「addresses」テーブルがあり、一対多の関係があります。MongoDB ではこれをどのようにモデル化しますか?
回答:
アドレスが顧客とともに頻繁にアクセスされ、数が多すぎない場合は、顧客ドキュメント内の配列として埋め込みます。アドレスが多い、または共有されている場合は、別の「addresses」コレクションを使用し、顧客ドキュメント内の _id で参照します。
MongoDB レプリカセットにはプライマリと 2 つのセカンダリがあります。プライマリがダウンしました。何が起こり、MongoDB はどのように高可用性を保証しますか?
回答:
プライマリがダウンすると、残りのメンバーが選挙を行います。セカンダリのいずれかが新しいプライマリに選出されます。このプロセスにより、高可用性と自動フェイルオーバーが保証され、通常は数秒で完了します。
2 つの異なるコレクションからのデータを結合し、複数の集計を実行する複雑な分析クエリを実行する必要があります。どの MongoDB 機能を使用しますか?
回答:
$lookup ステージを持つアグリゲーションパイプラインです。$lookup は、同じデータベース内のシャーディングされていないコレクションに対して左外部結合を実行し、複数のコレクションからのデータを結合してから、$group、$match、$sort のようなさらなる集計ステージを実行できるようにします。