0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MongoDB 初心者向けチートシート

0
Posted at

MongoDB チートシート

MongoDBは、JSONに近い形のデータを保存・検索・追加・変更・削除できるデータベースです。

SQLのような「テーブル」ではなく、MongoDBでは主に

Database
└─ Collection
   ├─ Document
   ├─ Document
   └─ Document

という構造になっています。

SQLとざっくり対応させると、

SQL MongoDB
Database Database
Table Collection
Row Document
Column Field

サンプルデータ

このチートシートでは users コレクションを使います。

{
    _id: ObjectId("..."),
    name: "田中",
    age: 16,
    email: "tanaka@example.com",
    prefecture: "Tokyo",
    active: true
}

複数あると、

[
    {
        name: "田中",
        age: 16,
        prefecture: "Tokyo"
    },
    {
        name: "佐藤",
        age: 18,
        prefecture: "Tokyo"
    },
    {
        name: "鈴木",
        age: 17,
        prefecture: "Chiba"
    }
]

こんな感じです。


1. データベースを選ぶ use

use mydb

意味:

mydb というデータベースを使う

存在しない場合でも、実際にデータを書き込むと作成されます。


2. 現在のデータベースを見る

db

データベース一覧:

show dbs

コレクション一覧:

show collections

3. 全データを見る find()

db.users.find()

意味:

users コレクションのデータを全部取得

SQLなら、

SELECT * FROM users;

に近いです。


4. 1件だけ取得する findOne()

db.users.findOne()

条件を付ける場合:

db.users.findOne({
    name: "田中"
})

5. 条件を付ける

名前が「田中」

db.users.find({
    name: "田中"
})

SQLなら、

WHERE name = '田中'

に相当します。


6. 数字を比較する

18歳以上

db.users.find({
    age: {
        $gte: 18
    }
})

18歳より大きい

db.users.find({
    age: {
        $gt: 18
    }
})

18歳以下

db.users.find({
    age: {
        $lte: 18
    }
})

18歳未満

db.users.find({
    age: {
        $lt: 18
    }
})

7. よく使う比較演算子

MongoDB 意味
$eq 等しい
$ne 等しくない
$gt より大きい
$gte 以上
$lt より小さい
$lte 以下
$in 候補のどれか
$nin 候補のどれでもない

例えば:

db.users.find({
    age: {
        $ne: 18
    }
})

18歳ではない人。


8. 範囲を指定する

16歳以上18歳以下:

db.users.find({
    age: {
        $gte: 16,
        $lte: 18
    }
})

SQLの、

WHERE age BETWEEN 16 AND 18

に近いです。


9. 複数条件

MongoDBでは普通にフィールドを並べると AND になります。

db.users.find({
    age: 18,
    active: true
})

意味:

age が18
かつ
active が true

10. $and

明示的に AND を書くこともできます。

db.users.find({
    $and: [
        { age: { $gte: 16 } },
        { age: { $lte: 18 } }
    ]
})

ただしこれは、

db.users.find({
    age: {
        $gte: 16,
        $lte: 18
    }
})

と書いた方が簡単です。


11. $or

田中または佐藤:

db.users.find({
    $or: [
        { name: "田中" },
        { name: "佐藤" }
    ]
})

SQLなら、

WHERE name = '田中'
OR name = '佐藤'

です。


12. $in

複数候補のどれか:

db.users.find({
    name: {
        $in: [
            "田中",
            "佐藤",
            "鈴木"
        ]
    }
})

これは、

$or

を大量に書くより便利です。


13. $nin

指定した値以外:

db.users.find({
    name: {
        $nin: [
            "田中",
            "佐藤"
        ]
    }
})

14. 文字列の部分一致・正規表現

「田」を含む:

db.users.find({
    name: /田/
})

「田」で始まる

db.users.find({
    name: /^田/
})

「中」で終わる

db.users.find({
    name: /中$/
})

大文字小文字を無視

db.users.find({
    name: /tanaka/i
})

15. $regex

同じことを $regex でも書けます。

db.users.find({
    name: {
        $regex: "田"
    }
})

大文字小文字を無視:

db.users.find({
    name: {
        $regex: "tanaka",
        $options: "i"
    }
})

16. 必要なフィールドだけ取得する

名前と年齢だけ:

db.users.find(
    {},
    {
        name: 1,
        age: 1
    }
)

ただし _id はデフォルトで表示されます。

消したい場合:

db.users.find(
    {},
    {
        _id: 0,
        name: 1,
        age: 1
    }
)

SQLなら、

SELECT name, age FROM users;

に近いです。


17. 並び替える sort()

小さい順

db.users.find().sort({
    age: 1
})

1 = 昇順

16
17
18

大きい順

db.users.find().sort({
    age: -1
})

-1 = 降順

18
17
16

18. 件数を制限する limit()

最初の10件:

db.users.find().limit(10)

19. データを飛ばす skip()

10件飛ばす:

db.users.find().skip(10)

10件飛ばして10件取得:

db.users
    .find()
    .skip(10)
    .limit(10)

ページネーションなどで使えます。


20. データを1件追加 insertOne()

db.users.insertOne({
    name: "山田",
    age: 17,
    email: "yamada@example.com"
})

MongoDBでは _id を指定しなければ、自動的に作られます。

例えば:

{
    _id: ObjectId("68db..."),
    name: "山田",
    age: 17
}

21. 複数件追加 insertMany()

db.users.insertMany([
    {
        name: "山田",
        age: 17
    },
    {
        name: "高橋",
        age: 18
    }
])

22. データを変更する updateOne()

IDが一致する人の年齢を18にする:

db.users.updateOne(
    {
        _id: ObjectId("xxxxxxxxxxxxxxxxxxxxxxxx")
    },
    {
        $set: {
            age: 18
        }
    }
)

構造は、

db.users.updateOne(
    条件,
    変更内容
)

です。


23. $set

値を設定・変更します。

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            age: 17
        }
    }
)

複数フィールド:

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            age: 17,
            active: true,
            prefecture: "Chiba"
        }
    }
)

24. $unset

フィールドを削除します。

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $unset: {
            email: ""
        }
    }
)

すると、

email

というフィールド自体が消えます。


25. $inc

数字を増減します。

年齢を1増やす:

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $inc: {
            age: 1
        }
    }
)

5増やす:

$inc: {
    score: 5
}

1減らす:

$inc: {
    score: -1
}

26. 複数データを変更 updateMany()

18歳未満を全員 inactive にする:

db.users.updateMany(
    {
        age: {
            $lt: 18
        }
    },
    {
        $set: {
            active: false
        }
    }
)

⚠ updateMany() の注意

これを実行すると、

db.users.updateMany(
    {},
    {
        $set: {
            active: false
        }
    }
)

usersの全データが変更されます。

{} は、

条件なし
= 全データ

という意味です。

変更する前に、

db.users.find({
    age: {
        $lt: 18
    }
})

で対象を確認すると安全です。


27. データを1件削除 deleteOne()

db.users.deleteOne({
    name: "田中"
})

条件に一致した最初の1件を削除します。


28. 複数削除 deleteMany()

18歳未満をすべて削除:

db.users.deleteMany({
    age: {
        $lt: 18
    }
})

⚠ deleteMany() の超重要注意

db.users.deleteMany({})

を実行すると、

usersコレクション内の全ドキュメントが削除されます。

SQLの、

DELETE FROM users;

に近いです。

実行する前に、

db.users.find({
    age: {
        $lt: 18
    }
})

で必ず確認すると安全です。


29. ドキュメント丸ごと置き換え replaceOne()

db.users.replaceOne(
    {
        name: "田中"
    },
    {
        name: "田中太郎",
        age: 17,
        active: true
    }
)

$set と違い、

ドキュメント全体を置き換える

ので注意します。


30. データが存在しなければ作る upsert

db.users.updateOne(
    {
        name: "山田"
    },
    {
        $set: {
            age: 17
        }
    },
    {
        upsert: true
    }
)

山田 が、

存在する → 更新
存在しない → 新規作成

となります。


31. 件数を数える

db.users.countDocuments()

条件付き:

db.users.countDocuments({
    age: {
        $gte: 18
    }
})

32. 重複なしの値を取得 distinct()

例えばデータが、

Tokyo
Tokyo
Chiba
Tokyo
Chiba

なら、

db.users.distinct("prefecture")

結果:

[
    "Tokyo",
    "Chiba"
]

33. null

メールアドレスが null:

db.users.find({
    email: null
})

ただしMongoDBでは、

{
    email: null
}

は、

email が null
または
email フィールド自体が存在しない

ドキュメントにも一致します。


34. フィールドが存在するか $exists

emailが存在する:

db.users.find({
    email: {
        $exists: true
    }
})

存在しない:

db.users.find({
    email: {
        $exists: false
    }
})

35. データ型を調べる $type

文字列:

db.users.find({
    name: {
        $type: "string"
    }
})

数字:

db.users.find({
    age: {
        $type: "number"
    }
})

36. ネストされたデータ

MongoDBではこういうデータを普通に保存できます。

{
    name: "田中",
    address: {
        prefecture: "Chiba",
        city: "Ichihara"
    }
}

37. ネストされたフィールドを検索

db.users.find({
    "address.prefecture": "Chiba"
})

. を使います。

address.prefecture

という書き方を ドット記法 といいます。


38. ネストされたフィールドを変更

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            "address.city": "Chiba"
        }
    }
)

39. 配列

MongoDBでは配列も保存できます。

{
    name: "田中",
    tags: [
        "minecraft",
        "linux",
        "mongodb"
    ]
}

40. 配列に値が含まれるか

db.users.find({
    tags: "minecraft"
})

これで、

tags: [
    "minecraft",
    "linux"
]

のようなドキュメントに一致します。


41. 配列が複数の値を含む $all

db.users.find({
    tags: {
        $all: [
            "minecraft",
            "linux"
        ]
    }
})

意味:

minecraft と linux の両方を含む

42. 配列の要素数 $size

タグが3個:

db.users.find({
    tags: {
        $size: 3
    }
})

43. 配列に追加 $push

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $push: {
            tags: "proxmox"
        }
    }
)

結果:

[
    "minecraft",
    "linux",
    "mongodb",
    "proxmox"
]

44. 重複なしで配列に追加 $addToSet

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $addToSet: {
            tags: "linux"
        }
    }
)

すでに linux があれば追加されません。


45. 配列から削除 $pull

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $pull: {
            tags: "minecraft"
        }
    }
)

46. 配列のオブジェクトを検索 $elemMatch

例えば、

{
    name: "田中",
    servers: [
        {
            name: "rack-srv",
            memory: 128
        },
        {
            name: "rog-srv",
            memory: 64
        }
    ]
}

というデータの場合、

db.users.find({
    servers: {
        $elemMatch: {
            name: "rack-srv",
            memory: {
                $gte: 128
            }
        }
    }
})

のように検索できます。


47. ObjectId

MongoDBでは標準の _id として、

ObjectId("68db...")

がよく使われます。

検索する場合:

db.users.findOne({
    _id: ObjectId("68db12345678901234567890")
})

これはダメな場合があります。

_id: "68db12345678901234567890"

なぜなら、

ObjectId

と

String

は別の型だからです。


48. 日付 Date

現在時刻:

new Date()

保存:

db.users.insertOne({
    name: "田中",
    createdAt: new Date()
})

日付で検索

db.users.find({
    createdAt: {
        $gte: new Date("2026-01-01")
    }
})

49. MongoDBの主なデータ型

型 例
String "hello"
Number 123
Boolean true
Object { name: "田中" }
Array ["linux", "mongodb"]
Null null
Date new Date()
ObjectId ObjectId("...")

50. Aggregation

MongoDBには、

aggregate()

という強力な集計機能があります。

SQLの、

GROUP BY
COUNT
SUM
AVG
JOIN

などに近い処理ができます。


51. $match

条件で絞る:

db.users.aggregate([
    {
        $match: {
            age: {
                $gte: 18
            }
        }
    }
])

通常の、

find({
    age: {
        $gte: 18
    }
})

に近いです。


52. $group

都道府県ごとの人数:

db.users.aggregate([
    {
        $group: {
            _id: "$prefecture",
            count: {
                $sum: 1
            }
        }
    }
])

結果:

[
    {
        _id: "Tokyo",
        count: 2
    },
    {
        _id: "Chiba",
        count: 1
    }
]

SQLなら、

SELECT prefecture, COUNT(*)
FROM users
GROUP BY prefecture;

に近いです。


53. 合計 $sum

例えば、

{
    name: "商品A",
    price: 1000
}

のようなデータなら、

db.products.aggregate([
    {
        $group: {
            _id: null,
            total: {
                $sum: "$price"
            }
        }
    }
])

54. 平均 $avg

db.users.aggregate([
    {
        $group: {
            _id: null,
            averageAge: {
                $avg: "$age"
            }
        }
    }
])

55. 最大・最小

db.users.aggregate([
    {
        $group: {
            _id: null,
            maxAge: {
                $max: "$age"
            },
            minAge: {
                $min: "$age"
            }
        }
    }
])

56. Aggregationで並び替え $sort

db.users.aggregate([
    {
        $sort: {
            age: -1
        }
    }
])

57. Aggregationで件数制限 $limit

db.users.aggregate([
    {
        $limit: 10
    }
])

58. Aggregationでフィールドを選択 $project

db.users.aggregate([
    {
        $project: {
            _id: 0,
            name: 1,
            age: 1
        }
    }
])

59. Aggregationを組み合わせる

18歳以上を年齢が高い順に10人:

db.users.aggregate([
    {
        $match: {
            age: {
                $gte: 18
            }
        }
    },
    {
        $sort: {
            age: -1
        }
    },
    {
        $limit: 10
    },
    {
        $project: {
            _id: 0,
            name: 1,
            age: 1
        }
    }
])

流れ:

$match
↓
18歳以上に絞る

$sort
↓
年齢が高い順

$limit
↓
10件

$project
↓
nameとageだけ表示

60. MongoDB版 JOIN $lookup

MongoDBでも別のコレクションを結合できます。

例えば、

users

{
    _id: 1,
    name: "田中"
}

posts

{
    title: "こんにちは",
    userId: 1
}

usersとpostsを結合:

db.users.aggregate([
    {
        $lookup: {
            from: "posts",
            localField: "_id",
            foreignField: "userId",
            as: "posts"
        }
    }
])

意味:

users._id
   ↓
posts.userId

をつなげます。

結果は、

{
    _id: 1,
    name: "田中",
    posts: [
        {
            title: "こんにちは",
            userId: 1
        }
    ]
}

のようになります。


61. インデックス

検索を高速化できます。

db.users.createIndex({
    name: 1
})

name でよく検索する場合などに使います。


62. 複合インデックス

db.users.createIndex({
    prefecture: 1,
    age: -1
})

例えば、

db.users.find({
    prefecture: "Tokyo"
}).sort({
    age: -1
})

のような検索で使える可能性があります。

複合インデックスではフィールドの順番も重要です。


63. UNIQUEインデックス

メールアドレスを重複不可にする:

db.users.createIndex(
    {
        email: 1
    },
    {
        unique: true
    }
)

これで、

test@example.com
test@example.com

のような重複を防げます。


64. インデックス一覧

db.users.getIndexes()

65. インデックス削除

名前を確認:

db.users.getIndexes()

削除:

db.users.dropIndex("name_1")

66. クエリがインデックスを使っているか確認 explain()

db.users.find({
    name: "田中"
}).explain("executionStats")

見るポイントの例:

IXSCAN

ならインデックス検索。

COLLSCAN

ならコレクション全体を走査しています。


67. コレクションを作る

db.createCollection("users")

ただしMongoDBでは、

db.users.insertOne({
    name: "田中"
})

のように書けば、存在しない users が自動的に作られることも多いです。


68. コレクションを削除

db.users.drop()

⚠ コレクションごと消えます。


69. データベースを削除

db.dropDatabase()

⚠ 現在選択しているデータベース全体が消えます。

実行前に、

db

で現在のデータベースを確認した方が安全です。


70. スキーマバリデーション

MongoDBは基本的に柔軟なスキーマですが、制限を付けることもできます。

db.createCollection("users", {
    validator: {
        $jsonSchema: {
            bsonType: "object",
            required: [
                "name",
                "age"
            ],
            properties: {
                name: {
                    bsonType: "string"
                },
                age: {
                    bsonType: "int"
                }
            }
        }
    }
})

これなら、

name → string必須
age  → int必須

のようにできます。


71. よく使うMongoDBコマンドまとめ

全件取得

db.users.find()

1件検索

db.users.findOne({
    name: "田中"
})

18歳以上

db.users.find({
    age: {
        $gte: 18
    }
})

追加

db.users.insertOne({
    name: "田中",
    age: 16
})

更新

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            age: 17
        }
    }
)

削除

db.users.deleteOne({
    name: "田中"
})

並び替え

db.users.find().sort({
    age: -1
})

最大10件

db.users.find().limit(10)

件数

db.users.countDocuments()

72. 特に覚えればいいもの

最初はこれだけでもかなり使えます。

find()

検索。

findOne()

1件検索。

insertOne()

追加。

updateOne()

変更。

deleteOne()

削除。

$set

値を変更。

$gte

以上。

$lte

以下。

$in

複数候補。

sort()

並び替え。

limit()

件数制限。

aggregate()

集計。


73. MongoDBを日本語っぽく読む

例えば:

db.users
    .find({
        age: {
            $gte: 18
        }
    })
    .sort({
        age: -1
    })
    .limit(10)

日本語にすると、

db.users
→ usersコレクションから

find
→ 検索

age: { $gte: 18 }
→ 年齢が18歳以上

sort({ age: -1 })
→ 年齢が高い順

limit(10)
→ 最大10件

つまり、

usersから18歳以上の人を年齢が高い順に最大10人取得する

という意味です。


74. update / delete前の安全確認

かなり重要です。

例えば削除したい場合、いきなり、

db.users.deleteMany({
    age: {
        $lt: 18
    }
})

を実行するのではなく、

まず、

db.users.find({
    age: {
        $lt: 18
    }
})

を実行します。

対象が正しいことを確認してから、

db.users.deleteMany({
    age: {
        $lt: 18
    }
})

を実行します。

updateも同じです。

まず:

db.users.find({
    name: "田中"
})

確認してから:

db.users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            age: 18
        }
    }
)

これだけでも事故をかなり防げます。


75. 超簡易まとめ

// 全件取得
db.users.find()

// 1件取得
db.users.findOne({
    name: "田中"
})

// 18歳以上
db.users.find({
    age: {
        $gte: 18
    }
})

// 追加
db.users.insertOne({
    name: "田中",
    age: 16
})

// 複数追加
db.users.insertMany([
    {
        name: "田中"
    },
    {
        name: "佐藤"
    }
])

// 更新
db.users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            age: 17
        }
    }
)

// 数字を増やす
db.users.updateOne(
    {
        name: "田中"
    },
    {
        $inc: {
            age: 1
        }
    }
)

// 1件削除
db.users.deleteOne({
    name: "田中"
})

// 複数削除
db.users.deleteMany({
    age: {
        $lt: 18
    }
})

// 並び替え
db.users.find().sort({
    age: -1
})

// 最大10件
db.users.find().limit(10)

// 10件飛ばす
db.users.find().skip(10)

// 件数
db.users.countDocuments()

// 重複なし
db.users.distinct("prefecture")

// インデックス作成
db.users.createIndex({
    name: 1
})

// 集計
db.users.aggregate([
    {
        $group: {
            _id: "$prefecture",
            count: {
                $sum: 1
            }
        }
    }
])

一番大事な注意

これ:

db.users.updateMany(
    {},
    {
        $set: {
            active: false
        }
    }
)

は全データを更新します。

これ:

db.users.deleteMany({})

は全データを削除します。

これ:

db.users.drop()

はコレクションそのものを削除します。

これ:

db.dropDatabase()

はデータベース全体を削除します。

迷ったら変更・削除する前に、

db.users.find({
    /* 同じ条件 */
})

を実行して、対象データを確認します。


Node.jsからMongoDBを使う超簡易版

インストール:

npm install mongodb

接続:

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

const client = new MongoClient(
    "mongodb://127.0.0.1:27017"
);

await client.connect();

const db = client.db("mydb");

const users = db.collection("users");

全件取得

const result = await users
    .find({})
    .toArray();

console.log(result);

1件取得

const user = await users.findOne({
    name: "田中"
});

console.log(user);

追加

await users.insertOne({
    name: "田中",
    age: 16
});

更新

await users.updateOne(
    {
        name: "田中"
    },
    {
        $set: {
            age: 17
        }
    }
);

削除

await users.deleteOne({
    name: "田中"
});

18歳以上

const usersOver18 = await users
    .find({
        age: {
            $gte: 18
        }
    })
    .toArray();

並び替え + 最大10件

const result = await users
    .find({})
    .sort({
        age: -1
    })
    .limit(10)
    .toArray();

ObjectIdで検索

const {
    MongoClient,
    ObjectId
} = require("mongodb");

const user = await users.findOne({
    _id: new ObjectId(
        "68db12345678901234567890"
    )
});

MongoDBをSQLと比較すると

やりたいこと SQL MongoDB
全件取得 SELECT * find()
条件検索 WHERE find({...})
1件取得 LIMIT 1 findOne()
追加 INSERT insertOne()
更新 UPDATE updateOne()
削除 DELETE deleteOne()
複数更新 UPDATE ... WHERE updateMany()
複数削除 DELETE ... WHERE deleteMany()
並び替え ORDER BY sort()
件数制限 LIMIT limit()
スキップ OFFSET skip()
件数 COUNT() countDocuments()
重複除去 DISTINCT distinct()
集計 GROUP BY $group
JOIN JOIN $lookup
インデックス CREATE INDEX createIndex()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?