まくろぐ
更新: / 作成:

全般(mongosh で接続した後のコマンド)

コマンド説明
db現在のデータベース名を表示
use <db>現在のデータベースを切り替える
show databases (dbs)データベースの一覧を表示
show collections (tables)コレクションの一覧を表示
show usersユーザーの一覧を表示
show logログの出力
db.stats()データベースの統計情報を表示
db.<coll>.stats()コレクションの統計情報を表示
db.createCollection("<coll>")コレクションを作成(オプション指定付きで作成したいとき)
db.getCollectionInfos()コレクション情報を JS 配列として取得
db.getCollectionNames()コレクション名の一覧を JS 配列として取得

ドキュメントの検索 (Find)

find の基本

コレクション内のドキュメントを検索するには、find() メソッドの第 1 引数に検索フィルターを指定します。

すべてのドキュメントを取得する
db.<coll>.find()
db.<coll>.find({})
name フィールドの値が value に一致するドキュメントを検索する
db.<coll>.find({ name: "value" })
awards.wins フィールドが 100 より大きいドキュメントを検索する
db.<coll>.find({ "awards.wins": { $gt: 100 } })
languages フィールドに jp あるいは en を含むドキュメントを検索する
db.<coll>.find({ languages: { $in: ["jp", "en"] } })

find() の第 2 引数 (project fields) では、取得するフィールドを指定できます。 基本的には取得したいフィールドに 1 を指定すれば OK ですが、_id フィールドだけはデフォルトで取得するようになっているので、_id フィールドが必要ない場合は明示的に 0 を指定する必要があります。

title フィールドと genres フィールドのみ取得する
db.<coll>.find({}, { _id: 0, title: 1, genres: 1 })

find() メソッドには、他にもさまざまな検索条件を指定できます。

フィルターの指定方法 find()

find の第 1 引数説明
{ age: 10 }age フィールド(数値)が 10 に完全一致
{ age: { $gt: 10 } }age フィールド(数値)が 10 より大きい
{ age: { $gte: 10 } }age フィールド(数値)が 10 以上
{ age: { $lt: 20 } }age フィールド(数値)が 20 未満
{ age: { $lte: 20 } }age フィールド(数値)が 20 以下
{ age: { $gte: 10, $lte: 20 } }age フィールド(数値)が 10 以上 20 以下
{ created: { $lt: ISODate("2000-01-01") } }created フィールド(日時)が 2000年1月1日 より前
{ name: "ほげ" }name フィールド(文字列)が ほげ に完全一致
{ name: /ほげ/ }
{ name: { $regex: "ほげ" } }
name フィールド(文字列)に ほげ が含まれる
{ name: /^ほげ/ }
{ name: { $regex: "^ほげ" } }
name フィールド(文字列)が ほげ で始まっている
{ name: /ほげ$/ }
{ name: { $regex: "ほげ$" } }
name フィールド(文字列)が ほげ で終わっている
{ genre: { $in: ["ACT", RPG"] } }genre フィールド(文字列)が ACTRPG のいずれか
{ genres: { $in: ["ACT", "RPG"] } }genres フィールド(配列)に少なくとも ACTRPG が含まれる
{ genres: { $in: ["ACT", "RPG"] } }genres フィールド(配列)に少なくとも ACTRPG が含まれる
{ genres: { $all: ["ACT", "RPG"] } }genres フィールド(配列)に ACTRPG の両方が含まれる
{ genres: { $size: 2 } }genres フィールド(配列)のサイズが 2
{ $and: [{ k1: v1 }, { k2: v2 }] }AND 条件
{ $or: [{ k1: v1 }, { k2: v2 }] }OR 条件
{ key: null }key フィールドが nullundefined、あるいは存在しない
{ key: { $type: "null" } }key フィールドが null (=データ型が Null)
{ key: { $exists: true }key フィールドが存在する
{ key: { $exists: false }key フィールドが存在しない

ソート sort()

db.<coll>.find().sort({ price: 1 })
price フィールドで昇順ソート
db.<coll>.find().sort({ date: -1 })
date フィールドで降順ソート
db.<coll>.find().sort({
  price: 1,
  date: -1
})
price フィールドで昇順ソート。
price フィールドの値が同じ場合は、さらに date フィールドで降順ソート。pricedate複合インデックスを張っておくと高速なソートが可能です。

取得件数を制限 limit()

コマンド説明
db.<coll>.find().limit(3)ドキュメントを最大 3 件取得
db.<coll>.find().sort({ age: -1 }).limit(3)年齢の高い順にドキュメントを最大 3 件取得

スキップ(ページング処理) skip()

コマンド説明
db.<coll>.find().skip(50).limit(10)先頭の 50 件をスキップして次の 10 件を取得

ドキュメントの追加 (Insert)

コマンド説明
db.<coll>.insertOne({...})1 つのドキュメントを追加
db.<coll>.insertMany([...])複数のドキュメントを追加

あるコレクションにドキュメントを追加しようとしたときに、コレクションが存在しない場合は自動的に生成されます。

実行例

1 つのドキュメントを追加
db.people.insertOne({
  name: { first: "Alan", last: "Turing" },
  birth: new Date("Jun 23, 1912"),
  death: new Date("Jun 07, 1954"),
  contribs: [ "Turing machine", "Turing test", "Turingery" ],
  views: Long(1250000)
})
複数のドキュメントを追加
db.books.insertMany([
  { title: "Title-1", stars: 0 },
  { title: "Title-2", stars: 0 },
  { title: "Title-3", stars: 0 },
])

ドキュメントの削除

コマンド説明
db.<coll>.deleteOne({ 検索条件 })検索条件に一致するドキュメントを 1 件削除
db.<coll>.deleteMany({ 検索条件 })検索条件に一致するドキュメントを全件削除
db.<coll>.deleteMany({})すべてのドキュメントを削除(危険)
db.<coll>.remove({ 検索条件 })remove() は MongoDB 4.0 で deprecated

ドキュメント削除の例

// 指定した ID のドキュメントを削除
db.books.deleteOne({ _id: ObjectId('6595345d07c7966c20e44b5d') })

// 指定した価格以上のドキュメントをすべて削除
db.books.deleteMany({ price: { $gte: 3000 } })

// すべてのドキュメントを削除(危険)
db.books.deleteMany({})

ドキュメントの更新 (Update)

コマンド説明
db.<coll>.updateOne(
  { 検索条件 },
  { $set: { 更新内容 } }
)
見つかったドキュメントを 1 件更新
db.<coll>.updateOne(
  { 検索条件 },
  { $set: { 更新内容 } },
  { upsert: true }
)
upsert 処理。ドキュメントが見つかったらその内容を更新。 見つからなかったら新規追加(検索条件と更新内容に指定されているフィールドが登録される)
db.<coll>.updateMany(
  { 検索条件 },
  { $set: { 更新内容 } }
)
見つかったドキュメントをすべて更新
db.<coll>.updateMany(
  {},
  { $set: { 更新内容 } }
)
すべてのドキュメントを更新(検索条件なし)
db.<coll>.updateMany(
  {},
  { $set: { "myArrayField.$[elem]": "置換後" } },
  { arrayFilters: [{ "elem": { $eq: "置換前" } }] }
)
配列フィールド内の値を置換
db.<coll>.replaceOne(
  { 検索条件 },
  { 更新内容 } }
)
見つかったドキュメントの内容を丸々置き換える(削除して追加するのと同じ)

見つかったドキュメントを 1 件更新

title が Title-1 の status を closed に更新
db.issues.updateOne(
  { title: "Title-1" },
  { $set: { status: "closed" } }
)

$set で指定したフィールドの値のみ更新されます。 $set で指定しなかったフィールドは元の値が維持されます。 元のドキュメントに存在しないフィールドを指定すると、フィールドが追加されます。

すべてのドキュメントを更新

すべてのドキュメントの stars をインクリメント (+1)
db.books.updateMany(
  {},
  { $inc: { stars: 1 } }
)

検索条件に空オブジェクト ({}) を指定することで、すべてのドキュメントを更新対象としています。 $set の代わりに $inc を使用すると、既存の値に対して値を加算できます。

配列フィールド内の値を置換

genres 配列フィールド内の OTHER という要素をまとめて ETC に置換する例です。

テスト用 JavaScript コード
// test コレクションの準備
db.test.deleteMany({})
db.test.insertMany([
  { _id: 1, genres: ["ACT", "RPG"] },
  { _id: 2, genres: ["STG", "OTHER"] },
  { _id: 3, genres: ["OTHER", "ACT"] },
])

// genres 配列フィールド内の OTHER を ETC に置換
db.test.updateMany(
  { "genres": { $exists: true } },
  { $set: { "genres.$[elem]": "ETC" } },
  { arrayFilters: [{ "elem": { $eq: "OTHER" } }] }
)

// 結果確認
db.test.find()
実行結果
[
  { _id: 1, genres: [ 'ACT', 'RPG' ] },
  { _id: 2, genres: [ 'STG', 'ETC' ] },
  { _id: 3, genres: [ 'ETC', 'ACT' ] }
]

updateMany() の検索条件(第 1 引数)には {} を渡すことも可能ですが、これだと genres フィールドが存在しないドキュメントがある場合にエラーになってしまうので、上記では { "genres": { $exists: true } } として、genres フィールドが存在するドキュメントに対してのみ置換処理するようにしています。

スキーマの更新

コマンド説明
db.<coll>.updateMany({}, { $rename: { oldKey: "newKey" } })フィールド名を変更

フィールド名を変更

次の例では、1 つのフィールド名をリネームしています(複数のフィールド名をまとめて変更することも可能です)。 検索条件に空オブジェクト ({}) を指定することで、すべてのドキュメントを更新対象としています。

categories フィールドの名前を genres に変更
db.books.updateMany(
  {},
  { $rename: { categories: "genres" } }
)

すべてのドキュメントが categories フィールドを持つことが保証されていない場合は、次のように絞り込んで置換します。

db.books.updateMany(
  { "categories": { $exists: true } },
  { $rename: { categories: "genres" } }
)

集計操作 (Aggregation Operations)

  • db.<coll>.aggregate([...])
    • データの集計操作を行います。タグやジャンルの一覧情報を生成したいときなどに使えます。

よくある集計操作を行うためのメソッドが組み込みメソッドとして提供されています (single purpose aggregation methods)。

指定方法説明
db.<coll>.estimatedDocumentCount()おおよそのドキュメント数を取得
db.<coll>.count()正確なドキュメント数を取得 (deprecated)
db.<coll>.distinct("tags")tags フィールドに現れる値を配列で取得

バックアップとリストア

DB 全体をバイナリデータ (BSON) でバックアップ&リストア

バックアップ
$ mongodump --uri mongodb+srv://<user>:<pass>@<cluster-url>/<db>

DB のダンプ結果は、./dump/<db>/<collection>.bson のようなパスに出力されます。

リストア
$ mongorestore --uri mongodb+srv://<user>:<pass>@<cluster-url> --db <db> ./dump

ユーザーに Database の書き込み権限が必要です。

コレクションを JSON ファイルにバックアップ&リストア

バックアップ
$ mongoexport --uri mongodb+srv://<user>:<pass>@<cluster-url>/<db> --collection <coll> --out backup.json
リストア
$ mongoimport --uri mongodb+srv://<user>:<pass>@<cluster-url>/<db> --collection <coll> --file backup.json

ユーザーに Database の書き込み権限が必要です。

インデックス

コマンド説明
db.<coll>.createIndex({ field: 1 })
score フィールド用のインデックスを作成
db.<coll>.createIndex({
  genre: 1,
  price: -1
})
genre と price フィールドの複合インデックスを作成(昇順+降順)
db.<coll>.createIndex({
  title: "text",
  comment: "text"
})
title と comment フィールド用にテキストインデックスを作成
db.<coll>.createIndex({ "$**": "text" })
全フィールド用のテキストインデックスを作成(ワイルドカードテキストインデックス)

MongoDB のインデックスの詳細ついてはこちらを参照

関連記事

まくろぐ
サイトマップまくへのメッセージ