MongoDBコマンド紹介:よく使う操作まとめ
はじめに
現代のアプリケーション開発において、データの永続化は不可欠な要素です。リレーショナルデータベース(RDB)が長らくその中心を担ってきましたが、データの構造が柔軟に変化する現代において、NoSQLデータベースの重要性が増しています。その中でも、ドキュメント指向データベースの代表格であるMongoDBは、開発の俊速性やスケーラビリティの高さから、多くの開発者に選ばれています。
MongoDBは、BSON(Binary JSON)形式のドキュメントとしてデータを格納し、スキーマレスな設計が可能です。これにより、データの構造変更が容易になり、アジャイル開発との相性が非常に良いという特徴があります。また、高いパフォーマンスと豊富な機能(レプリケーション、シャーディング、集計フレームワークなど)を備えています。
この記事では、MongoDBを使い始める上で、あるいは日常的な開発・運用で最も頻繁に利用するコマンドについて、詳細な説明と具体的な使用例を交えながら徹底的に解説します。データベースの選択から、コレクションの管理、そして最も重要なドキュメントのCRUD(Create, Read, Update, Delete)操作、さらにはパフォーマンス向上に不可欠なインデックス操作まで、幅広くカバーします。
MongoDBの操作は通常、mongosh
という対話型のシェルを通じて行います。この記事で紹介するコマンドは、基本的にこのmongosh
での実行を想定しています。
さあ、MongoDBの世界へ踏み出し、その強力な機能を使いこなすための第一歩を踏み出しましょう。
MongoDBの基本概念
MongoDBの操作を理解するためには、いくつかの基本的な概念を把握しておく必要があります。
-
ドキュメント (Document)
- MongoDBにおけるデータの基本単位です。
- キーと値のペアの集まりであり、RDBにおける行(Row)やレコードに似ています。
- BSON形式で格納されます。BSONはJSONに似ていますが、より多くのデータ型(バイナリデータ、日付、その他の数値型など)をサポートしており、効率的なストレージと高速な走査を可能にします。
- ドキュメントはネストされたドキュメントや配列を含むことができます。これにより、複雑な階層構造や関連データを一つのドキュメント内に保持することが可能です。
- 全てのドキュメントには、プライマリキーとして機能する一意な
_id
フィールドがあります。明示的に指定しない場合、MongoDBが自動的にObjectId
型の値を生成して割り当てます。
-
コレクション (Collection)
- 関連するドキュメントの集まりです。RDBにおけるテーブル(Table)に似ています。
- 同じコレクション内のドキュメントは、必ずしも同じ構造(スキーマ)を持っている必要はありません。これがMongoDBのスキーマレスまたはスキーマオンリードと呼ばれる特徴です。
- コレクションは、データベース内に存在します。
-
データベース (Database)
- 関連するコレクションのコンテナです。RDBにおけるデータベース(Database)に似ています。
- MongoDBサーバーは複数のデータベースをホストできます。
- 各データベースはファイルシステム上の異なるディレクトリに保存されます。
-
mongosh (MongoDB Shell)
- MongoDBと対話するための公式なJavaScriptインタープリターシェルです。
- コマンドラインからMongoDBサーバーに接続し、データベースやコレクションの操作、ドキュメントのCRUD操作、管理タスクなどを実行できます。
- この記事で紹介するコマンドは、全てこの
mongosh
で実行することを前提としています。
これらの概念を理解した上で、具体的な操作コマンドを見ていきましょう。
データベース操作
MongoDBサーバーに接続したら、まずどのデータベースを操作するかを選択する必要があります。また、データベースの一覧を表示したり、不要になったデータベースを削除したりする操作も頻繁に行われます。
データベースの選択: use <database_name>
- 構文:
javascript
use <database_name> - 説明:
指定した名前のデータベースに切り替えます。
もし指定した名前のデータベースが存在しない場合、その名前の新しいデータベースが作成されます。ただし、データベースはコレクションが作成され、最初のドキュメントが挿入されるまで、物理的には存在しない(ファイルシステム上に作成されない)ことに注意が必要です。つまり、use non_existent_db
と実行しただけでは、show dbs
のリストには表示されません。そのデータベースにコレクションを作成し、ドキュメントを一つでも挿入すると、初めてデータベースが「存在」する状態になり、show dbs
で表示されるようになります。 - 使用例:
myAppDb
という名前のデータベースに切り替える(存在しない場合は作成される):
javascript
use myAppDb
実行すると、シェルのプロンプトが切り替わったデータベース名(例:myAppDb>
)に変わります。- デフォルトの
test
データベースに切り替える:
javascript
use test
- 注意点:
- データベース名は、大文字小文字を区別します。
- 特定の文字(例: スペース,
.
など)はデータベース名に使用できません。詳細はMongoDBのドキュメントを参照してください。
データベースの一覧表示: show dbs
または show databases
- 構文:
javascript
show dbs
// または
show databases - 説明:
現在のMongoDBインスタンスに存在するデータベースの一覧と、それぞれのデータベースのサイズを表示します。 - 使用例:
javascript
show dbs
出力例:
admin 0.000GB
config 0.000GB
local 0.000GB
myAppDb 0.001GBadmin
,config
,local
はMongoDBのシステムが使用する特別なデータベースです。通常、これらのデータベースを直接操作する必要はありません。- データベースのサイズは、データファイルの使用量を示します。
現在のデータベースの確認: db
- 構文:
javascript
db - 説明:
現在選択されているデータベースの名前を表示します。これは、use
コマンドでどのデータベースに切り替わったかを確認するのに便利です。 - 使用例:
myAppDb
データベースを選択した後にdb
コマンドを実行:
javascript
use myAppDb
db
出力例:
myAppDb
データベースの削除: db.dropDatabase()
- 構文:
javascript
db.dropDatabase() - 説明:
現在選択されているデータベースとその中に含まれる全てのコレクションおよびドキュメントを完全に削除します。この操作は元に戻せません。 -
使用例:
myAppDb
データベースを削除:
javascript
use myAppDb
db.dropDatabase()
出力例:
{ "dropped" : "myAppDb", "ok" : 1 }
ok: 1
は操作が成功したことを示します。
-
注意点:
- このコマンドは現在選択されているデータベースに対して実行されます。削除したいデータベースに
use
コマンドで切り替えてから実行してください。 - システムデータベース(
admin
,config
,local
)を削除しようとすると、通常はエラーになるか、削除できないようになっています。
- このコマンドは現在選択されているデータベースに対して実行されます。削除したいデータベースに
コレクション操作
データベースを選択したら、次はコレクションを扱います。コレクションの作成、一覧表示、名前変更、削除といった操作が必要です。
コレクションの作成: db.createCollection("<collection_name>")
- 構文:
javascript
db.createCollection("<collection_name>", <options>) - 説明:
指定した名前の新しいコレクションを作成します。
MongoDBでは、最初のドキュメントがコレクションに挿入されたときにコレクションが自動的に作成されるため、通常、このコマンドを明示的に使用する必要はありません。しかし、特定のオプション(例えば、上限コレクションの作成やドキュメント検証ルールの設定など)を指定したい場合にcreateCollection
を使用します。オプションはJSON形式のオブジェクトで指定します。 - オプション例:
capped: true
: 上限コレクションを作成します。これは固定サイズのコレクションで、新しいドキュメントが追加されると、最も古いドキュメントが自動的に削除されます。ログ記録などに向いています。size: <size_in_bytes>
: 上限コレクションの最大サイズを指定します。max: <max_documents>
: 上限コレクションの最大ドキュメント数を指定します。validator: { ... }
: ドキュメント検証ルールを指定します。挿入または更新されるドキュメントがこのルールを満たしているかチェックできます。
- 使用例:
- オプションを指定せずに
users
コレクションを作成:
javascript
use myAppDb // myAppDbを選択
db.createCollection("users")
出力例:
{ "ok" : 1 }
- サイズ1MBの上限コレクション
logs
を作成:
javascript
db.createCollection("logs", { capped: true, size: 1048576 })
- オプションを指定せずに
- 注意点:
- コレクション名は、大文字小文字を区別します。
- 特定の文字(例:
$
)はコレクション名に使用できません。詳細はMongoDBのドキュメントを参照してください。 - 多くの場合、明示的な作成は不要です。
db.collection_name.insertOne({...})
などの最初のドキュメント挿入コマンドを実行したときに、コレクションは自動的に作成されます。
コレクションの一覧表示: show collections
または show tables
- 構文:
javascript
show collections
// または
show tables - 説明:
現在選択されているデータベースに存在するコレクションの一覧を表示します。 - 使用例:
myAppDb
データベースに存在するコレクションを表示:
javascript
use myAppDb
show collections
出力例:
users
products
コレクションの名前変更: db.collection_name.renameCollection("new_collection_name")
- 構文:
javascript
db.<current_collection_name>.renameCollection("<new_collection_name>", <dropTarget>) - 説明:
指定したコレクションの名前を変更します。
dropTarget
オプション(デフォルトはfalse
)をtrue
に設定すると、新しい名前のコレクションが既に存在する場合に、名前変更前に既存のコレクションを削除します。 - 使用例:
users
コレクションの名前をappUsers
に変更:
javascript
use myAppDb
db.users.renameCollection("appUsers")
新しい名前のappUsers
コレクションが既に存在する場合に、それを削除して名前変更を行う:
javascript
db.users.renameCollection("appUsers", true) - 注意点:
- 名前変更操作は、大規模なコレクションに対しては時間がかかる場合があります。
- 名前変更中は、そのコレクションに対する操作がブロックされる可能性があります。
コレクションの削除: db.collection_name.drop()
- 構文:
javascript
db.<collection_name>.drop() - 説明:
指定したコレクションとその中に含まれる全てのドキュメントを完全に削除します。この操作も元に戻せません。 -
使用例:
appUsers
コレクションを削除:
javascript
use myAppDb
db.appUsers.drop()
出力例:
true
- 操作が成功すると
true
を返します。失敗した場合はfalse
を返します。
- 操作が成功すると
-
注意点:
- このコマンドは、現在選択されているデータベース内の指定したコレクションに対して実行されます。
- 削除するコレクションの名前を正確に指定してください。
ドキュメント操作 (CRUD)
MongoDBにおける最も中心的な操作は、ドキュメントのCRUD(Create, Read, Update, Delete)です。これらの操作を行うためのコマンドは非常に頻繁に使用されます。
C (Create): ドキュメントの挿入
新しいドキュメントをコレクションに追加します。
insertOne()
- 構文:
javascript
db.<collection_name>.insertOne(<document>, <options>) - 説明:
コレクションに単一のドキュメントを挿入します。挿入するドキュメントはJavaScriptオブジェクトとして指定します。
_id
フィールドをドキュメントに含めなかった場合、MongoDBが自動的にObjectId
を生成して割り当てます。 - 使用例:
users
コレクションに新しいユーザーを追加:
javascript
use myAppDb
db.users.insertOne({
name: "Alice",
age: 30,
email: "[email protected]",
address: {
street: "123 Main St",
city: "Anytown",
zip: "12345"
},
hobbies: ["reading", "hiking"]
})
出力例:
{
acknowledged: true,
insertedId: ObjectId("...") // 自動生成された_id
}
_id
を明示的に指定して挿入:
javascript
db.users.insertOne({
_id: 1,
name: "Bob",
age: 25
}) - 戻り値:
挿入が成功したかどうかを示すacknowledged
フィールドと、挿入されたドキュメントの_id
を含むオブジェクトを返します。
insertMany()
- 構文:
javascript
db.<collection_name>.insertMany([<document1>, <document2>, ...], <options>) - 説明:
コレクションに複数のドキュメントをまとめて挿入します。挿入するドキュメントの配列を最初の引数として指定します。
デフォルトでは、配列内のいずれかのドキュメントの挿入に失敗した場合、残りのドキュメントの挿入は中断されます(順序保証モード)。options
としてordered: false
を指定すると、失敗が発生しても他のドキュメントの挿入は続行されます(順序非保証モード)。 - 使用例:
products
コレクションに複数の商品をまとめて追加:
javascript
use myAppDb
db.products.insertMany([
{ name: "Laptop", price: 1200, category: "Electronics" },
{ name: "Mouse", price: 25, category: "Electronics" },
{ name: "Keyboard", price: 75, category: "Electronics" },
{ name: "Book", price: 20, category: "Books" }
])
出力例:
{
acknowledged: true,
insertedIds: {
'0': ObjectId("..."),
'1': ObjectId("..."),
'2': ObjectId("..."),
'3': ObjectId("...")
}
} -
戻り値:
挿入が成功したかどうかを示すacknowledged
フィールドと、挿入されたドキュメントそれぞれのインデックスと_id
のマッピングを含むinsertedIds
フィールドを含むオブジェクトを返します。 -
_id
フィールドについて:- 全てのドキュメントは、プライマリキーとして機能する一意な
_id
フィールドを持つ必要があります。 - 明示的に指定しない場合、MongoDBドライバーまたはシェルが
ObjectId
という特別な型の値を生成して割り当てます。 ObjectId
は、生成時刻、マシン識別子、プロセスID、カウンターを含む12バイトの値で、分散環境でもユニーク性が高いことが保証されます。- 自分で
_id
を指定することも可能ですが、その場合はコレクション内で一意であることを保証する必要があります。文字列、数値、日付など、様々なデータ型を_id
として使用できます。
- 全てのドキュメントは、プライマリキーとして機能する一意な
R (Read): ドキュメントの検索
コレクションから条件に合致するドキュメントを取得します。検索操作は非常に多機能で、様々な条件指定、ソート、ページネーションなどが可能です。
find()
- 構文:
javascript
db.<collection_name>.find(<query>, <projection>).sort(<sort>).skip(<skip>).limit(<limit>) -
説明:
コレクションから条件に合致するドキュメントを検索します。
find()
メソッドはカーソルを返します。デフォルトでは、mongosh
はカーソルから最初の20個のドキュメントを表示し、さらに表示するかどうかを尋ねます(”Type it to continue…”)。すべての結果を見たい場合は、カーソルをループ処理する必要がありますが、シェルでは通常自動的に行われます。
検索結果に対して、後続のメソッド(.sort()
,.skip()
,.limit()
,.projection()
– これは.find()
の第二引数と同じ機能)をチェーンして適用できます。 -
基本的な使い方 (全件検索):
引数なしでfind()
を呼び出すと、コレクション内の全てのドキュメントを取得します。
javascript
use myAppDb
db.users.find()
出力例:
[
{ _id: ObjectId("..."), name: "Alice", age: 30, email: "[email protected]", address: { ... }, hobbies: [...] },
{ _id: 1, name: "Bob", age: 25 },
// ... 他のユーザー
] -
検索条件の指定 (Query Filter):
find()
の最初の引数にクエリドキュメント(検索条件を指定するJavaScriptオブジェクト)を渡します。これは、RDBのWHERE
句に相当します。- 完全一致: フィールドと値のペアを指定します。
javascript
// nameが"Alice"のユーザーを検索
db.users.find({ name: "Alice" }) - ネストされたフィールド: ドット記法(
.
)を使用して、ネストされたドキュメント内のフィールドを指定します。
javascript
// address.cityが"Anytown"のユーザーを検索
db.users.find({ "address.city": "Anytown" }) - 配列内の要素: 配列に特定の要素が含まれているドキュメントを検索します。
javascript
// hobbies配列に"hiking"が含まれているユーザーを検索
db.users.find({ hobbies: "hiking" }) -
比較演算子:
$eq
(equals),$ne
(not equals),$gt
(greater than),$lt
(less than),$gte
(greater than or equal to),$lte
(less than or equal to),$in
(in an array),$nin
(not in an array) などを使用します。
“`javascript
// ageが30より大きいユーザーを検索
db.users.find({ age: { $gt: 30 } })// priceが50から100の間(両端含む)の商品を検索
db.products.find({ price: { $gte: 50, $lte: 100 } })// categoryが”Electronics”または”Books”の商品を検索
db.products.find({ category: { $in: [“Electronics”, “Books”] } })
* **論理演算子:** `$and`, `$or`, `$not`, `$nor` を使用して、複数の条件を組み合わせます。
javascript
// ageが20より大きく、かつcityが”Anytown”のユーザーを検索
db.users.find({ $and: [{ age: { $gt: 20 } }, { “address.city”: “Anytown” }] })
// または、暗黙的な$and(トップレベルで複数のフィールドを指定すると$andとして扱われる)
db.users.find({ age: { $gt: 20 }, “address.city”: “Anytown” })// ageが20より小さいか、またはcityが”Anytown”のユーザーを検索
db.users.find({ $or: [{ age: { $lt: 20 } }, { “address.city”: “Anytown” }] })// ageが25ではないユーザーを検索
db.users.find({ age: { $ne: 25 } }) // $not: { age: 25 } と同じ意味ではないので注意// ageが20より小さい、かつ、cityが”Anytown”ではないユーザーを検索
db.users.find({ $nor: [{ age: { $lt: 20 } }, { “address.city”: “Anytown” }] })
* **要素演算子:** `$exists` (フィールドが存在するか), `$type` (フィールドのBSON型)
javascript
// emailフィールドが存在するユーザーを検索
db.users.find({ email: { $exists: true } })// ageフィールドが数値型であるユーザーを検索
db.users.find({ age: { $type: “number” } }) // または { $type: 16 } (BSONタイプコード)
* **配列演算子:** `$all` (配列が指定された全ての要素を含む), `$elemMatch` (配列の要素が複数の条件を満たす), `$size` (配列のサイズ)
javascript
// hobbies配列に”reading”と”hiking”の両方が含まれているユーザーを検索 (順番不問)
db.users.find({ hobbies: { $all: [“reading”, “hiking”] } })// hobbies配列に”reading”が含まれているユーザーを検索 ($allなしでもOK)
db.users.find({ hobbies: “reading” })// 複雑な配列要素の条件 (例: タグ配列の各要素が { name: …, value: … } のようなドキュメントの場合)
// tags配列内に nameが”color” かつ valueが”red” の要素が存在するドキュメントを検索
// db.items.find({ tags: { $elemMatch: { name: “color”, value: “red” } } })// hobbies配列のサイズが2であるユーザーを検索
db.users.find({ hobbies: { $size: 2 } })
* **正規表現:** `$regex` を使用してパターンマッチングを行います。
javascript
// nameが”A”で始まるユーザーを検索 (大文字小文字を区別しない場合は $options: “i”)
db.users.find({ name: { $regex: “^A”, $options: “i” } })
“`
- 完全一致: フィールドと値のペアを指定します。
-
特定のフィールドの取得 (Projection):
find()
の第二引数にプロジェクションドキュメントを渡します。これにより、取得するドキュメントに含めるフィールドまたは除外するフィールドを指定できます。1
を指定するとそのフィールドを含めます(_id
以外のフィールドを一つでも指定した場合、_id
はデフォルトで含まれますが、_id: 0
で除外できます)。0
を指定するとそのフィールドを除外します(_id
以外のフィールドは0
と1
を混在させられません)。
“`javascript
// nameとemailフィールドのみを取得 (ageフィールドは含まない)
db.users.find({}, { name: 1, email: 1 })
// nameとemailフィールドのみを取得し、_idフィールドを除外
db.users.find({}, { name: 1, email: 1, _id: 0 })// passwordフィールドを除外して全てのフィールドを取得
// (実際にはパスワードをドキュメントに保存するのは避けるべきですが例として)
// db.users.find({}, { password: 0 })
“` -
結果のソート (Sort):
.sort()
メソッドを使用し、ソート条件を指定するドキュメントを渡します。フィールド名の後に1
を指定すると昇順、-1
を指定すると降順になります。複数のフィールドでソートすることも可能です。
“`javascript
// ageフィールドで昇順にソート
db.users.find().sort({ age: 1 })// ageで降順にソートし、ageが同じ場合はnameで昇順にソート
db.users.find().sort({ age: -1, name: 1 })
“` -
結果のスキップと制限 (Skip, Limit):
.skip()
メソッドでスキップするドキュメント数を、.limit()
メソッドで取得する最大ドキュメント数を指定します。これらはページネーションによく使用されます。
“`javascript
// 最初の10件をスキップし、次の5件を取得 (2ページ目を表示、1ページあたり5件の場合)
db.products.find().skip(10).limit(5)// 最大3件の商品を取得
db.products.find().limit(3)
“`
* 注意点: 大量のドキュメントをスキップする操作は、パフォーマンスに影響を与える可能性があります。特に、インデックスが付いていないフィールドでソートしつつ大量にスキップする場合などです。 -
カーソルについて:
find()
は実際には結果のドキュメントそのものではなく、カーソルオブジェクトを返します。カーソルは、検索結果セットへのポインタのようなものです。mongosh
は便宜上、最初の20件を表示してくれますが、プログラムからはカーソルを明示的に操作して結果を逐次取得します。find().toArray()
とすると、結果を全てメモリ上の配列として取得できます(ただし、結果セットが大きい場合はメモリ消費に注意が必要です)。
findOne()
- 構文:
javascript
db.<collection_name>.findOne(<query>, <projection>) - 説明:
コレクションから条件に合致するドキュメントのうち、最初に見つかった1件だけを取得します。
find().limit(1)
と似ていますが、findOne()
はカーソルではなく単一のドキュメントまたはnull
を直接返します。 - 使用例:
_id
がObjectId("...")
のユーザーを取得:
javascript
use myAppDb
db.users.findOne({ _id: ObjectId("...") })
ageが25のユーザーのうち最初に見つかった1件を取得し、nameとemailのみ表示:
javascript
db.users.findOne({ age: 25 }, { name: 1, email: 1 }) -
戻り値:
条件に合致するドキュメントが見つかった場合はそのドキュメント、見つからなかった場合はnull
を返します。 -
find()
vsfindOne()
:- 1件だけ取得したい場合は、
findOne()
の方がシンプルで、カーソルのオーバーヘッドがないためわずかに効率的です。 - 複数のドキュメントを取得する場合は、常に
find()
を使用します。
- 1件だけ取得したい場合は、
U (Update): ドキュメントの更新
コレクション内の既存のドキュメントを変更します。
updateOne()
- 構文:
javascript
db.<collection_name>.updateOne(<filter>, <update>, <options>) - 説明:
指定したfilter
に合致するドキュメントのうち、最初に見つかった1件だけを更新します。
update
引数には、ドキュメント全体で置き換える場合は新しいドキュメントを、特定のフィールドだけを変更する場合は更新演算子を使用したドキュメントを指定します。通常は更新演算子を使用します。 - オプション:
upsert: true
:filter
に合致するドキュメントが見つからなかった場合、filter
とupdate
を組み合わせて新しいドキュメントを作成し挿入します。collation: <collation_document>
: 文字列比較のための照合順序を指定します。
- 使用例:
name
が”Alice”のユーザーのage
を31に更新し、新しいフィールドstatus
を追加:
javascript
use myAppDb
db.users.updateOne(
{ name: "Alice" }, // Filter
{
$set: { age: 31, status: "active" } // Update using $set operator
}
)
_id
がObjectId("...")
のユーザーのaddress.city
を”Newtown”に更新:
javascript
db.users.updateOne(
{ _id: ObjectId("...") },
{ $set: { "address.city": "Newtown" } }
)
name
が”Charlie”のユーザーを探し、いなければ新規作成(upsert):
javascript
db.users.updateOne(
{ name: "Charlie" },
{ $set: { age: 22, status: "pending" } },
{ upsert: true } // Upsert option
) - 戻り値:
更新操作の結果を含むオブジェクトを返します。これには、matchedCount
(フィルタに合致したドキュメント数)、modifiedCount
(実際に変更されたドキュメント数)、upsertedId
(upsertで新規作成された場合の_id
)などが含まれます。
javascript
// 更新成功の例
{ acknowledged: true, matchedCount: 1, modifiedCount: 1 }
// upsert成功の例
{ acknowledged: true, matchedCount: 0, modifiedCount: 0, upsertedId: ObjectId("...") }
updateMany()
- 構文:
javascript
db.<collection_name>.updateMany(<filter>, <update>, <options>) - 説明:
指定したfilter
に合致する全てのドキュメントを更新します。updateOne
と同様に、更新には通常更新演算子を使用します。 - オプション:
updateOne
と同じオプション(upsert
を除く)が利用可能です。updateMany
ではupsert
オプションはサポートされていません。 - 使用例:
category
が”Electronics”の商品全ての価格を10%値上げ:
javascript
use myAppDb
db.products.updateMany(
{ category: "Electronics" },
{ $mul: { price: 1.1 } } // $mul operator (multiply)
)
status
フィールドがない全てのユーザーにstatus: "inactive"
を追加:
javascript
db.users.updateMany(
{ status: { $exists: false } },
{ $set: { status: "inactive" } }
) - 戻り値:
updateOne
と同様に、matchedCount
とmodifiedCount
を含むオブジェクトを返します。
javascript
{ acknowledged: true, matchedCount: 3, modifiedCount: 3 } // 3件の商品が更新された例
replaceOne()
- 構文:
javascript
db.<collection_name>.replaceOne(<filter>, <replacement>, <options>) - 説明:
指定したfilter
に合致するドキュメントのうち、最初に見つかった1件を、指定したreplacement
ドキュメントで完全に置き換えます。_id
フィールドは置き換えられませんが、それ以外のフィールドは全て新しいドキュメントの内容になります。 - オプション:
upsert: true
オプションが利用可能です。 - 使用例:
name
が”Bob”のユーザーのドキュメント全体を、よりシンプルな新しいドキュメントで置き換え:
javascript
use myAppDb
db.users.replaceOne(
{ name: "Bob" },
{ name: "Robert", occupation: "Engineer", age: 26 } // Replacement document
) - 戻り値:
updateOne
と同様のオブジェクトを返します。modifiedCount
が1の場合、置き換えが発生したことを示します。
更新演算子 (Update Operators):
更新操作では、ドキュメント全体を置き換えるのではなく、特定のフィールドに対して様々な変更を加えるために更新演算子を使用するのが一般的です。主要なものをいくつか紹介します。
$set
: 指定したフィールドの値を設定します。フィールドが存在しない場合は新規に追加します。
javascript
{ $set: { status: "active", lastLogin: new Date() } }$unset
: 指定したフィールドをドキュメントから削除します。
javascript
{ $unset: { email: "", address: "" } } // 値はなんでもよい$inc
: 数値フィールドの値を指定した量だけ増加または減少させます。
javascript
{ $inc: { age: 1, loginCount: 5 } } // ageを1増やし、loginCountを5増やす$mul
: 数値フィールドの値を指定した量だけ乗算します。
javascript
{ $mul: { price: 1.1 } } // priceを1.1倍する$push
: 配列フィールドに要素を追加します。配列が存在しない場合は新しい配列を作成します。
javascript
{ $push: { hobbies: "gardening" } } // hobbies配列に"gardening"を追加
{ $push: { tags: { $each: ["new", "urgent"] } } } // 複数の要素を追加$addToSet
: 配列フィールドに要素を追加しますが、その要素が既に配列に存在する場合は追加しません(セットとして扱います)。
javascript
{ $addToSet: { hobbies: "reading" } } // "reading"がなければ追加
{ $addToSet: { tags: { $each: ["new", "sale"] } } }$pop
: 配列の最初(1を指定)または最後(-1を指定)の要素を削除します。
javascript
{ $pop: { history: 1 } } // history配列の最初の要素を削除
{ $pop: { queue: -1 } } // queue配列の最後の要素を削除$pull
: 配列フィールドから指定した値に一致する全ての要素を削除します。
javascript
{ $pull: { hobbies: "hiking" } } // hobbies配列から"hiking"を全て削除
{ $pull: { tags: { $in: ["old", "temp"] } } } // "old"または"temp"に一致する要素を全て削除$pullAll
: 配列フィールドから指定した値のリストに一致する全ての要素を削除します。
javascript
{ $pullAll: { hobbies: ["reading", "hiking"] } } // hobbies配列から"reading"と"hiking"を全て削除$rename
: フィールドの名前を変更します。
javascript
{ $rename: { "email": "primaryEmail", "address.zip": "address.postalCode" } }
D (Delete): ドキュメントの削除
コレクションからドキュメントを削除します。
deleteOne()
- 構文:
javascript
db.<collection_name>.deleteOne(<filter>, <options>) - 説明:
指定したfilter
に合致するドキュメントのうち、最初に見つかった1件だけを削除します。 - 使用例:
name
が”Charlie”のユーザーを削除:
javascript
use myAppDb
db.users.deleteOne({ name: "Charlie" })
_id
がObjectId("...")
のユーザーを削除:
javascript
db.users.deleteOne({ _id: ObjectId("...") }) - 戻り値:
削除操作の結果を含むオブジェクトを返します。これには、deletedCount
(実際に削除されたドキュメント数)が含まれます。
javascript
{ acknowledged: true, deletedCount: 1 }
deleteMany()
- 構文:
javascript
db.<collection_name>.deleteMany(<filter>, <options>) - 説明:
指定したfilter
に合致する全てのドキュメントを削除します。
フィルタを空のオブジェクト{}
にすると、コレクション内の全てのドキュメントを削除します。これは、db.collection_name.drop()
とは異なり、コレクション自体は残ります。 - 使用例:
status
が”inactive”の全てのユーザーを削除:
javascript
use myAppDb
db.users.deleteMany({ status: "inactive" })
category
が”Books”で、price
が20より小さい全ての商品を削除:
javascript
db.products.deleteMany({ category: "Books", price: { $lt: 20 } })
logs
コレクションの全てのドキュメントを削除(コレクションは残る):
javascript
db.logs.deleteMany({}) - 戻り値:
deleteOne
と同様に、deletedCount
を含むオブジェクトを返します。
javascript
{ acknowledged: true, deletedCount: 5 } // 5件のドキュメントが削除された例 - 注意点:
deleteMany({})
はコレクションの全件削除ですが、db.collection_name.drop()
の方が通常は高速です。ただし、コレクションを残したい場合はdeleteMany({})
を使用します。- 削除操作は元に戻せません。実行前にフィルタ条件をよく確認してください。
インデックス操作
インデックスは、MongoDBがクエリを効率的に実行するために使用する特殊なデータ構造です。適切なインデックスを使用すると、クエリのパフォーマンスを劇的に向上させることができます。
インデックスの作成: createIndex()
/ createIndexes()
- 構文:
javascript
db.<collection_name>.createIndex(<key_document>, <options>)
// または複数のインデックスを作成する場合
db.<collection_name>.createIndexes([<index1_document>, <index2_document>, ...]) - 説明:
コレクションに新しいインデックスを作成します。
key_document
には、インデックスを作成するフィールドとそのソート順序(1: 昇順, -1: 降順)を指定します。複数のフィールドを指定すると複合インデックスになります。
options
には、インデックスのタイプ(ユニーク、TTLなど)や作成方法を指定します。 - 使用例:
name
フィールドに単一フィールドインデックスを作成(昇順):
javascript
use myAppDb
db.users.createIndex({ name: 1 })age
とname
フィールドに複合インデックスを作成(age降順、name昇順):
javascript
db.users.createIndex({ age: -1, name: 1 })email
フィールドにユニークインデックスを作成(重複するemailの挿入を禁止):
javascript
db.users.createIndex({ email: 1 }, { unique: true })createdAt
フィールドにTTL(Time-To-Live)インデックスを作成(60秒後にドキュメントを自動削除):
javascript
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 })- インデックスをバックグラウンドで作成(作成中にコレクションへのアクセスをブロックしない):
javascript
db.users.createIndex({ status: 1 }, { background: true }) // 非推奨、デフォルトがバックグラウンド作成
// MongoDB 4.2以降、createIndexはデフォルトでバックグラウンド実行されるため、通常このオプションは不要です。 - 複数のインデックスをまとめて作成:
javascript
db.products.createIndexes([
{ key: { name: 1 } },
{ key: { category: 1, price: -1 } }
])
- 注意点:
- インデックスはディスク容量を消費し、書き込み操作(挿入、更新、削除)のオーバーヘッドを増加させます。クエリのパフォーマンス向上と書き込みコストのバランスを考慮してインデックスを設計する必要があります。
- クエリで頻繁に使用されるフィールドや、ソート、グループ化に使用されるフィールドにインデックスを作成することを検討してください。
- 複合インデックスのフィールド順序は重要です。クエリのフィルタ条件とソート条件に合わせて設計してください。
インデックスの一覧表示: getIndexes()
- 構文:
javascript
db.<collection_name>.getIndexes() - 説明:
指定したコレクションに存在する全てのインデックスの定義(キー、オプションなど)を表示します。 - 使用例:
users
コレクションのインデックスを表示:
javascript
use myAppDb
db.users.getIndexes()
出力例:
[
{ v: 2, key: { _id: 1 }, name: '_id_' }, // デフォルトで作成される_idインデックス
{ v: 2, key: { name: 1 }, name: 'name_1' },
{ v: 2, key: { age: -1, name: 1 }, name: 'age_-1_name_1' },
{ v: 2, key: { email: 1 }, name: 'email_1', unique: true }
]
インデックスの削除: dropIndex()
/ dropIndexes()
-
構文:
“`javascript
db..dropIndex(“ “)
// またはインデックス定義ドキュメントを指定
// db..dropIndex( ) // 全てのインデックスを削除 (_idインデックスを除く)
db..dropIndexes()
* **説明:**
javascript
指定したインデックスをコレクションから削除します。
インデックス名は、`getIndexes()`の出力で確認できます。または、インデックス作成時に指定したキーパターンをそのままドキュメントとして指定することもできます。
`dropIndexes()`は、コレクションの`_id`インデックスを除く全てのインデックスを削除します。
* **使用例:**
`name_1`という名前のインデックスを削除:
use myAppDb
db.users.dropIndex(“name_1”)
`{ age: -1, name: 1 }`というキーパターンのインデックスを削除:
javascript
db.users.dropIndex({ age: -1, name: 1 })
`products`コレクションの`_id`以外の全てのインデックスを削除:
javascript
db.products.dropIndexes()
``
dropIndexes()`は全てのユーザー定義インデックスを削除するため、注意して使用してください。
* **注意点:**
* インデックスの削除は、そのインデックスに依存するクエリのパフォーマンスに影響を与える可能性があります。
*
インデックスとクエリパフォーマンスの関係
MongoDBのクエリプランナーは、利用可能なインデックスを評価し、最も効率的な実行計画(Query Plan)を選択します。
find()
やaggregate()
などのクエリメソッドに.explain("executionStats")
をチェーンして実行すると、MongoDBがどのようにクエリを実行したか、どのインデックスを使用したか、何件のドキュメントをスキャンしたかなどの詳細な情報を確認できます。これにより、クエリのパフォーマンスボトルネックを特定し、インデックスの設計を改善することができます。
例えば、インデックスを使用せずに大規模なコレクションを検索すると、MongoDBはコレクション全体をスキャンする必要があります(Collection Scan)。適切なインデックスがあれば、インデックスを使用して関連するドキュメントだけを効率的に見つけることができます(Index Scan または Index Seek)。
その他の便利・管理操作
日常的なCRUDやインデックス操作以外にも、状況確認や管理に役立つコマンドがあります。
コレクションの統計情報: stats()
- 構文:
javascript
db.<collection_name>.stats() - 説明:
指定したコレクションに関する様々な統計情報を表示します。これには、ドキュメント数、データサイズ、インデックスサイズなどが含まれます。 - 使用例:
users
コレクションの統計情報を表示:
javascript
use myAppDb
db.users.stats()
出力例 (一部抜粋):
javascript
{
ns: 'myAppDb.users', // データベースとコレクション名
size: 102400, // データサイズ (バイト)
count: 100, // ドキュメント数
storageSize: 49152, // ディスク上のストレージサイズ (圧縮など含む)
avgObjSize: 1024, // ドキュメントあたりの平均サイズ
wiredTiger: { ... }, // 使用しているストレージエンジンの詳細情報
nindexes: 4, // インデックス数
totalIndexSize: 32768, // 全インデックスの合計サイズ (バイト)
indexSizes: { // 各インデックスのサイズ
_id_: 8192,
name_1: 8192,
age_-1_name_1: 8192,
email_1: 8192
},
...
} - 注意点:
統計情報はスナップショットです。特にアクティブなコレクションでは、情報がすぐに古くなる可能性があります。
コレクションのカウント: countDocuments()
/ estimatedDocumentCount()
- 構文:
javascript
db.<collection_name>.countDocuments(<filter>, <options>)
db.<collection_name>.estimatedDocumentCount(<options>) - 説明:
countDocuments()
: 指定したfilter
に合致するドキュメントの数を正確にカウントします。フィルタなしの場合は、コレクション内の全てのドキュメント数をカウントします。このメソッドは、フィルタに合致するドキュメントを正確に数える必要がある場合に適していますが、大規模なコレクションに対しては時間がかかることがあります。estimatedDocumentCount()
: コレクション内のドキュメント数を推定します。これはメタデータを利用するため、非常に高速ですが、結果は概算値であり正確ではありません。正確なカウントが不要で、高速な概算値で十分な場合に適しています。
- 使用例:
users
コレクションの全てのドキュメント数を正確にカウント:
javascript
use myAppDb
db.users.countDocuments({})
age
が30より大きいユーザーの数を正確にカウント:
javascript
db.users.countDocuments({ age: { $gt: 30 } })
products
コレクションのドキュメント数を高速に推定:
javascript
db.products.estimatedDocumentCount() - 注意点:
古いcount()
メソッドは非推奨です。新しいコードではcountDocuments()
またはestimatedDocumentCount()
を使用してください。どちらを使用するかは、正確性が必要か、速度が優先されるかによって判断します。
Explain Plan の利用: .explain()
- 構文:
javascript
db.<collection_name>.<query_method>(...).explain(<verbosity>) - 説明:
find()
,aggregate()
,update()
,delete()
などのクエリメソッドにチェーンして使用すると、実際にクエリを実行せずに、MongoDBがそのクエリをどのように実行するかを示す実行計画(Explain Plan)を取得できます。verbosity
オプション:queryPlanner
(デフォルト): クエリプランナーが選択した計画の情報のみを表示します。executionStats
: 選択された計画の実行統計情報(ドキュメントスキャン数、インデックススキャン数、実行時間など)を表示します。最も一般的に使用されます。allPlansExecution
: プランナーが評価した全ての候補計画の実行統計情報を表示します。デバッグ用です。
- 使用例:
age
が30より大きいユーザーを検索するクエリの実行統計情報を表示:
javascript
use myAppDb
db.users.find({ age: { $gt: 30 } }).explain("executionStats")
この出力を見ることで、どのインデックスが使用されたか(winningPlan.inputStage.indexName
)、何件のインデックスキーがスキャンされたか(totalKeysExamined
)、何件のドキュメントがスキャンされたか(totalDocsExamined
)、実行に要した時間(executionTimeMillis
)などが分かります。totalDocsExamined
がcount
(全ドキュメント数)に近い場合、コレクションスキャンが発生している可能性が高く、インデックスが必要かもしれません。
シェルからのJavaScript実行
mongosh
はJavaScript環境を提供するため、単純なコマンドだけでなく、JavaScriptコードを記述してより複雑な操作や自動化タスクを実行できます。
- ループ処理:
javascript
use myAppDb
// 全てのユーザーのageを1増やす(推奨されない方法 - updateManyを使うべきだが例として)
db.users.find().forEach(function(user) {
db.users.updateOne(
{ _id: user._id },
{ $inc: { age: 1 } }
);
}); - 変数の利用:
javascript
let myUser = db.users.findOne({ name: "Alice" });
if (myUser) {
print("Found user: " + myUser.name + ", Age: " + myUser.age);
} else {
print("User not found.");
} - スクリプトファイルの実行:
-f
オプションを使用して、外部のJavaScriptファイルをmongosh
で実行できます。
bash
mongosh mongodb://<host>:<port>/<database> -f /path/to/your/script.js
トランザクション (Replica Set 環境)
MongoDB 4.0以降、レプリカセット環境でマルチドキュメントACIDトランザクションがサポートされました。これは、複数のドキュメントに対する一連の操作をアトミックに実行し、全て成功するか全て失敗するかを保証する機能です。
-
構文例 (シェルから):
“`javascript
use myAppDb
const session = db.getMongo().startSession(); // セッションを開始session.startTransaction(); // トランザクションを開始
try {
// トランザクション内で操作を実行
session.getDatabase(‘myAppDb’).collection(‘accounts’).updateOne(
{ _id: 1, balance: { $gte: 100 } },
{ $inc: { balance: -100 } },
{ session } // セッションを渡す
);session.getDatabase('myAppDb').collection('accounts').updateOne( { _id: 2 }, { $inc: { balance: 100 } }, { session } // セッションを渡す ); // エラーがなければコミット session.commitTransaction(); print("Transaction committed.");
} catch (error) {
// エラーが発生したらアボート
session.abortTransaction();
print(“Transaction aborted: ” + error);
} finally {
// セッションを終了
session.endSession();
}
“`
* 注意点:
* トランザクションはレプリカセットまたはシャーディングされたクラスター環境でのみ利用可能です。スタンドアロンインスタンスでは使用できません。
* トランザクションの使用にはいくつかの制約とパフォーマンスへの考慮事項があります。詳細はMongoDBのドキュメントを参照してください。これは日常的な基本操作というよりは、特定の要件(例えば、口座間の送金など)を満たすための高度な機能です。
実践的な例
ここでは、架空のオンラインストアの商品リストを管理するシナリオを想定し、これまでに紹介したコマンドを組み合わせて使用する実践的な例を見てみましょう。
前提: onlineStore
というデータベースと、products
というコレクションがあるとします。
“`javascript
// データベースを選択
use onlineStore
// 必要であればコレクションを作成(通常は最初の挿入で自動作成)
// db.createCollection(“products”)
// 初期データの挿入
db.products.insertMany([
{ _id: 1, name: “Laptop Pro”, brand: “BrandX”, category: “Electronics”, price: 1200, stock: 50, tags: [“tech”, “sale”] },
{ _id: 2, name: “Mechanical Keyboard”, brand: “BrandY”, category: “Electronics”, price: 75, stock: 200, tags: [“gaming”, “tech”] },
{ _id: 3, name: “Wireless Mouse”, brand: “BrandY”, category: “Electronics”, price: 25, stock: 150, tags: [“tech”] },
{ _id: 4, name: “Desk Lamp”, brand: “BrandZ”, category: “Home & Office”, price: 40, stock: 80 },
{ _id: 5, name: “Notebook (Pack of 3)”, brand: “BrandA”, category: “Stationery”, price: 10, stock: 300 },
{ _id: 6, name: “Fountain Pen”, brand: “BrandA”, category: “Stationery”, price: 30, stock: 50, tags: [“writing”, “gift”] },
{ _id: 7, name: “Laptop Stand”, brand: “BrandX”, category: “Home & Office”, price: 55, stock: 100, tags: [“tech”] }
])
“`
例 1: 特定の条件で商品を検索し、一部のフィールドだけを表示
BrandXの商品で、価格が100ドル以上のものを検索し、商品名と価格だけを表示します。
javascript
db.products.find(
{ brand: "BrandX", price: { $gte: 100 } }, // フィルタ条件
{ name: 1, price: 1, _id: 0 } // プロジェクション (nameとpriceを含め、_idを除外)
)
例 2: 配列要素と価格範囲を組み合わせた検索
タグに”tech”が含まれており、価格が50ドル以下の商品を検索します。
javascript
db.products.find({
tags: "tech", // tags配列に"tech"が含まれる
price: { $lte: 50 } // priceが50以下
})
例 3: 論理演算子を使用した複雑な検索
カテゴリーが”Electronics”または”Stationery”で、かつ在庫が100個未満の商品を検索します。
javascript
db.products.find({
$or: [ // 論理OR
{ category: "Electronics" },
{ category: "Stationery" }
],
stock: { $lt: 100 } // 在庫が100未満
})
例 4: 商品情報の更新
IDが1の商品の価格を1150ドルに値下げし、タグに”featured”を追加します。
javascript
db.products.updateOne(
{ _id: 1 }, // IDで特定のドキュメントをフィルタ
{
$set: { price: 1150 }, // 価格を変更
$addToSet: { tags: "featured" } // "featured"タグを追加 (重複なし)
}
)
例 5: 複数商品の在庫更新
カテゴリーが”Stationery”の商品の在庫を全て10個増やします。
javascript
db.products.updateMany(
{ category: "Stationery" }, // カテゴリーでフィルタ
{ $inc: { stock: 10 } } // stockを10増加
)
例 6: 在庫ゼロの商品を削除
在庫が0の商品を全て削除します。
javascript
db.products.deleteMany({ stock: 0 })
例 7: コレクションの統計情報とカウント
コレクション内の全商品数と統計情報を確認します。
javascript
db.products.countDocuments({}) // 正確なカウント
db.products.estimatedDocumentCount() // 高速な概算
db.products.stats() // 統計情報
例 8: パフォーマンス分析のためのExplain Plan
価格で降順ソートするクエリの実行計画を確認します。(もしpriceフィールドにインデックスがなければ、このクエリはコレクションスキャンになる可能性が高いです。)
javascript
db.products.find().sort({ price: -1 }).explain("executionStats")
もしtotalDocsExamined
がドキュメント数とほぼ同じであれば、price
フィールドにインデックスを作成することを検討します。
“`javascript
// priceフィールドに降順インデックスを作成
db.products.createIndex({ price: -1 })
// 再度Explain Planを確認し、totalKeysExaminedが減少しているか、IXSCANが使われているかを見る
db.products.find().sort({ price: -1 }).explain(“executionStats”)
“`
これらの例は、基本的なCRUD操作とインデックス操作を組み合わせることで、実際のアプリケーションで必要となる多様なデータ操作がMongoDBでいかに簡単に行えるかを示しています。
よくある質問とトラブルシューティング (簡単なもの)
-
コマンドがエラーになる、期待通りの結果が得られない。
- 構文エラー: JavaScriptの構文、括弧、カンマ、コロン、引用符などが間違っていないか確認してください。
mongosh
はエラーメッセージを表示しますが、詳細でない場合もあります。 - コレクション名/フィールド名のtypo: 大文字小文字を含め、名前が正確か確認してください。
show collections
やgetIndexes()
で確認できます。 - データベースの選択ミス:
db
コマンドで現在選択されているデータベースを確認してください。 - フィルタ条件の誤り: 意図したドキュメントがフィルタに合致する条件になっているか、特に比較演算子や論理演算子の使い方を確認してください。
- 更新演算子の使い方: 更新操作で
$set
などの演算子を正しく使用しているか確認してください。演算子なしでドキュメントを渡すと、replaceOne
のようにドキュメント全体が置き換わってしまう可能性があります。
- 構文エラー: JavaScriptの構文、括弧、カンマ、コロン、引用符などが間違っていないか確認してください。
-
_id
は自分で指定すべきか?- 特別な理由がない限り、MongoDBに自動生成させるのが推奨されます。
ObjectId
は分散環境での一意性が高く、挿入順に近い順序になるため、インデックス利用やレプリケーション効率の面で有利です。 - 外部システムからのIDを使用する必要がある場合や、特定のデータ型を
_id
としたい場合にのみ自分で指定を検討してください。その際、コレクション全体で一意であることを保証する責任は開発者にあります。
- 特別な理由がない限り、MongoDBに自動生成させるのが推奨されます。
-
find()
とfindOne()
の選び方- 結果が1件だけ必要であることが分かっている(例えば、
_id
で検索する場合など)場合は、findOne()
を使用します。シンプルで効率的です。 - 複数の結果が得られる可能性がある場合、または検索結果に対してソート、スキップ、リミットなどの操作を行いたい場合は、
find()
を使用します。
- 結果が1件だけ必要であることが分かっている(例えば、
-
大規模なデータに対する操作が遅い。
- 最も可能性が高い原因はインデックス不足です。クエリで使用しているフィルタ条件やソートキーに対応するインデックスが存在するか、
explain()
で確認してください。 - フィルタに合致するドキュメント数が非常に多い場合や、複雑な集計処理を行っている場合も遅くなる可能性があります。Aggregation Frameworkの最適化や、データの設計(例えば、関連データを一つのドキュメントに埋め込むなど)を見直す必要があるかもしれません。
- 最も可能性が高い原因はインデックス不足です。クエリで使用しているフィルタ条件やソートキーに対応するインデックスが存在するか、
まとめ
この記事では、MongoDBの日常的な操作に不可欠なコマンド群を詳細に解説しました。データベースとコレクションの基本操作から始まり、最も使用頻度の高いドキュメントのCRUD(Create, Read, Update, Delete)操作、そしてパフォーマンスチューニングに不可欠なインデックス操作まで、それぞれのコマンドの構文、説明、具体的な使用例、そして注意点を網羅的に紹介しました。
MongoDBの柔軟なドキュメントモデルと豊富なクエリ機能は、様々な種類のアプリケーション開発に適しています。これらの基本コマンドを習得することで、MongoDBを使ったデータ操作の基盤をしっかりと築くことができます。
学習はここで終わりではありません。MongoDBには、ここでは触れられなかった高度な機能が数多くあります。例えば:
- Aggregation Framework: データの変換、グループ化、集計を行うための強力なパイプラインベースのフレームワーク。RDBの
GROUP BY
,JOIN
,WINDOW FUNCTIONS
などに相当する複雑な処理が可能です。 - 地理空間クエリ: 位置情報データを効率的に検索・分析するための機能。
- 全文検索: テキストデータを検索するための機能(MongoDB Atlas Searchや旧バージョンのテキストインデックス)。
- レプリケーション: データの冗長性と高可用性を実現するための機能。
- シャーディング: 大規模なデータを水平分散して格納し、高いスケーラビリティを実現するための機能。
- セキュリティ: ユーザー認証、ロールベースのアクセス制御、暗号化などの機能。
これらの高度なトピックについても、公式ドキュメントや専門的なリソースで学習を深めることをお勧めします。
この記事が、MongoDBの基本操作を理解し、実際の開発や運用で自信を持ってコマンドを使えるようになるための一助となれば幸いです。MongoDBの旅を楽しんでください!