MongoDB 入門|研修コースに参加してみた
今回参加したコースは MongoDB 入門 です。
MongoDB はこれまで SE カレッジでも NoSQL を紹介するコースなどでちょこちょこと登場していましたが、今回はじめて単独コースとして開催されました。 個人的な印象ではまだまだ使われていないだろうなと思っていると、今年 2022 年 7 月の Stack Overflow の調査では、
- 使っているデータベース
- 第 4 位 28.3 % (1 位は MySQL で 46.85 %)
- 好きなデータベース
- 第 3 位 60.51 % (1 位は PostgreSQL で 72.08 %)
世界的にとてもシェアがあるものでした。
なぜ、そこまで IT エンジニアの支持があるのでしょうか? このコースに参加してみると、その独自のプログラマブルなクエリに人気の秘密が伺えました!
では、どのような内容だったのか、レポートします!
もくじ
コース情報
想定している受講者 | 特になし |
---|---|
受講目標 |
|
講師紹介
縦(チップ ~ AI ~ ビジネス SaaS まで技術スタックの広さ)にも横にも幅広い技術領域を教えられる 植田崇靖 さんが登壇されました。 今回は同じデータベースでも横展開できるところを見せていただきました。
「電子回路から機械学習まで、学ぶことが楽しい!」
MongoDB とは
まずは NoSQL から紐解かれたのですが、これは別の記事で触れているので、割愛します。
続いて、 MongoDB の特徴を紹介いただきました。
- NoSQL の一つでドキュメントデータベース
- JSON をそのまま格納できる
- RDBMS との用語の違い
- table を collection
- row を document
- column を field
- primary key を _id
MySQL / PostgreSQL でも JSON 型を扱うようになったので、両者の違いはわかりくくなりましたが、 2022 年 6 月の発表で MongoDB はナント、時系列データが扱えるようになったとのこと。 IoT などからのデータ、ログなど捌けるようになったのは大きいですね。
MongoDB が時系列データ対応、サーバレス対応、 HTTPS 経由での API 操作対応など機能強化を相次いで発表 - Publickey
MongoDB を使ってみよう
では、 MongoDB を使ってみ … る前に環境構築です。
コースでは Ubuntu 上でインストールを進めたのですが、このレポートでは MongoDB をオンラインで試せる Playground を使用しました。
読者の方で MongoDB を使ってみたい、という方はぜひお試しください(この記事のコードはすべて動きます)。
コレクション Collection
MongoDB のインストールができたところで、操作してみましょう。
まずはコレクション( = RDBMS のテーブル)を作ります。
- member というコレクションを作る
> db.createCollection("member") { "ok" : 1 }
- ドキュメント( = RDBMS でいうレコード、行)を保存
// insertOne で 1 つのドキュメント追加 > db.member.insertOne( {name: "suzuki", age: 30} ) { "acknowledged" : true, "insertedId" : ObjectId("6369b464c93d1986c90e426e") }
- 保存できたか確認
find()
が SQL で言う SELECT
> db.member.find() { "_id" : ObjectId("6369b464c93d1986c90e426e"), "name" : "suzuki", "age" : 30 }
_id
が RDBMS でいう主キー
- JavaScript も使える(下のコードは 10 件のドキュメントを保存するもの)
> let loop = 10 for(let i = 0; i < loop; i++) { db.member.insertOne({name: "satoh" + i}) } { "acknowledged" : true, "insertedId" : ObjectId("6369b62d7451815c45c3cdbe") }
- 出力してみる
> db.member.find() { "_id" : ObjectId("6369b62d7451815c45c3cdb4"), "name" : "suzuki", "age" : 30 } { "_id" : ObjectId("6369b62d7451815c45c3cdb5"), "name" : "satoh0" } { "_id" : ObjectId("6369b62d7451815c45c3cdb6"), "name" : "satoh1" } { "_id" : ObjectId("6369b62d7451815c45c3cdb7"), "name" : "satoh2" } { "_id" : ObjectId("6369b62d7451815c45c3cdb8"), "name" : "satoh3" } { "_id" : ObjectId("6369b62d7451815c45c3cdb9"), "name" : "satoh4" } { "_id" : ObjectId("6369b62d7451815c45c3cdba"), "name" : "satoh5" } { "_id" : ObjectId("6369b62d7451815c45c3cdbb"), "name" : "satoh6" } { "_id" : ObjectId("6369b62d7451815c45c3cdbc"), "name" : "satoh7" } { "_id" : ObjectId("6369b62d7451815c45c3cdbd"), "name" : "satoh8" } { "_id" : ObjectId("6369b62d7451815c45c3cdbe"), "name" : "satoh9" }
この JavaScript が使えるところがとってもユニーク! というよりも .
でつなげて出力が JSON というのはママ JavaScript です。
コース目標に
MongoDB を利用するために必要なプログラミングの基礎を学習する
とあるのは、こういうことだったのですね。
Capped Collection
MongoDB らしい特徴として、コレクションの一つ Capped コレクションも紹介いただきました。
- データ量、データ件数の上限を設定したコレクションのこと
- 上限に達すると、古いものから削除される
- ログでよく使われる
こちらも使ってみましょう。
- Capped コレクションを作成
> db.createCollection( "log", {capped: true, size: 1024000} // 件数の上限は max: 5000 などで指定 ) { "ok" : 1 }
- コレクションを Capped コレクションに変更
> db.runCommand( {"convertToCapped": "mycol", size: 10000} ) { "ok" : 1 }
CRUD をやってみよう
MongoDB に慣れるために、 CRUD (Create / Read / Update / Delete) 処理をやってみましょう。
insert
まずは insert 、ドキュメントの追加です。
- 複数件の登録
> db.member.insertMany([ {name: "satoh", age: 26}, {name: "yamaguchi", age: 31}, {name: "maeda", age: 44} ]) { "acknowledged" : true, "insertedIds" : [ ObjectId("6369bc99a8f04b03a9157914"), ObjectId("6369bc99a8f04b03a9157915"), ObjectId("6369bc99a8f04b03a9157916") ] }
- 確認
> db.member.find() { "_id" : ObjectId("6369bc99a8f04b03a9157914"), "name" : "satoh", "age" : 26 } { "_id" : ObjectId("6369bc99a8f04b03a9157915"), "name" : "yamaguchi", "age" : 31 } { "_id" : ObjectId("6369bc99a8f04b03a9157916"), "name" : "maeda", "age" : 44 }
- 確認
- 配列も登録できる
> db.member.insertOne({ name: "takada", childName: ["ichiro", "hanako"] }) { "acknowledged" : true, "insertedId" : ObjectId("6369bd3e0320649eeb9d7a1f") }
- 確認
> db.member.find() # 中略 { "_id" : ObjectId("6369bd3e0320649eeb9d7a1f"), "name" : "takada", "childName" : [ "ichiro", "hanako" ]
- 確認
- オブジェクトも登録できる
> db.member.insertOne({ name: "takagi", child1: {name: "jiro", age: 5}, child2: {name: "yume", age: 3}, }) { "acknowledged" : true, "insertedId" : ObjectId("6369bdec18fc6ce2ac1baa06") }
- 確認
> db.member.find() # 中略 { "_id" : ObjectId("6369bdec18fc6ce2ac1baa06"), "name" : "takagi", "child1" : { "name" : "jiro", "age" : 5 }, "child2" : { "name" : "yume", "age" : 3 } }
- 確認
これは完全にプログラミングですね。 JavaScript を使う開発者からすると、 SQL を書かずに、 ORM をかまさずに、 JavaScript でプログラムを書く延長線でデータベースを操作できるのはとても便利ですね。
一時 MEAN (MongoDB / Express / Angular / Node.js) スタックとして有名になったのは、「なるほど、 JavaScript で地続きにいけるからか」と今さら納得しました。
find
続いては find 、ドキュメント検索です。
前提として以下のようなドキュメントを登録した searchTest というコレクションを作成済みです。
{
name: "takeda",
age: 25,
skill: ["Java","MySQL","Python","MongoDB"],
child: [
{name: "ichiro", age: 5},
{name: "hanako", age:3}
]
}
{
name: "satoh",
age: 22,
skill: ["JavaScript", "SQL Server", "Python", "MongoDB"]
}
find の基本
> db.コレクション名.find(<検索条件>, <取得したいフィールド>)
SQL の SELECT のあとに WHERE 句などを使って様々な条件で検索できるように、 MongoDB でも同じように様々な検索条件を指定できます。
よく使うものから紹介いただきました。
- フィールド( RDBMS で言う column )の指定
> db.member.find( {}, // 空なので条件なし {_id: 0, name: 1} // field の指定。 ここでは name ) { "name" : "satoh" } { "name" : "yamaguchi" } { "name" : "maeda" } { "name" : "satoh" }
- _id を 0 に指定しているので、今回は表示されない
- 完全一致で検索
> db.searchTest.find( {name: "takeda"}, {_id: 0, "child.name": 1} ) { "child" : [ { "name" : "ichiro" }, { "name" : "hanako" } ] }
- 部分一致で検索
> db.member.find( {name: /ka/}, {_id: 0} ) { "name" : "takada", "childName" : [ "ichiro", "hanako" ] } { "name" : "takagi", "child1" : { "name" : "jiro", "age" : 5 }, "child2" : { "name" : "yume", "age" : 3 } }
/ /
で検索語句を指定する( "" がいらない)- 前方一致は
/^ /
- 後方一致は
/ $/
- 範囲指定検索
> db.member.find( {age: {$lte: 30}}, {_id: 0} ) { "name" : "satoh", "age" : 26 }
- 以下は
$lte
で指定 - 未満は
$lt
で指定 - 以上は
$gte
で指定 - より大きいは
$gt
で指定 - SQL の BETWEEN のように範囲指定したい場合は組み合わせる
> db.member.find( {age: {$gte: 25, $lte: 30}}, {_id: 0} ) { "name" : "satoh", "age" : 26 }
- 以下は
- and 検索
> db.member.find( { $and: [ {name: "satoh"}, {age: {$gte: 20}} ] }, {_id: 0} ) { "name" : "satoh", "age" : 26 }
$and
に配列で入れる- or 検索の場合も同様に
$or
を使って配列で指定
- null の扱い
- 空文字なら String 、 null 指定なら null 型、 undefined なら値が無いという扱い
- null の検索は
$exists: false
のように指定する
- 検索条件をすべて満たす配列を検索
> db.searchTest.find( {skill: {$all: ["Java", "MySQL"]} }, {_id: 0, name:1, skill:1} ) { "name" : "takeda", "skill" : [ "Java", "MySQL", "Python", "MongoDB" ] }
$all
で指定する
- オブジェクトの検索
> db.searchTest.find( {"child.age": 5}, {_id: 0, name: 1, child: 1} ) { "name" : "takeda", "child" : [ { "name" : "ichiro", "age" : 5 }, { "name" : "hanako", "age" : 3 } ] }
- オブジェクトの中身を検索する場合は
""
をつける child.age
のように指定する
- オブジェクトの中身を検索する場合は
- ソートや件数制限
> db.member.find( {}, {_id: 0} ).sort({age: 1}).limit(2) { "name" : "takada", "childName" : [ "ichiro", "hanako" ] }
find()
のあとに.sort()
と.limit()
のように繋げる
配列やオブジェクトをそのまま気軽にどんどん追加できるのは、とても柔軟性があるのですが、一方で検索するときは大変です ... 。
MongoDB の設計でも正規化、多 対 多のようなルールがあるのでしょうか。
update
続いては update 、ドキュメントの更新です。
- update の構文
> db.member.updateOne( {name: "satoh"}, {$set: {"age": 27}} )
- 確認
> db.member.find( {name: "satoh"}, {_id: 0} ) { "name" : "satoh", "age" : 27 }
- 複数フィールドの場合は
updateMany()
を使う replaceOne()
を使うと、 _id 以外のフィールドの値を変更できる
- 確認
- フィールドの追加
> db.member.updateOne( {name: "yamaguchi"}, {$set: {height: 170, weight: 60}} )
- 確認
> db.member.find( {name: "yamaguchi"}, {_id: 0} ) { "name" : "yamaguchi", "age" : 31, "height" : 170, "weight" : 60 }
- 確認
- 配列に要素を追加
> db.searchTest.updateOne( {name: "satoh"}, {$set: {"skill.3": "Ruby"}} )
skill.3
で添字 3 にデータを追加- オブジェクトの場合も同じように
child.1.height
のように指定して追加する - 結果
{ "name" : "satoh", "age" : 22, "skill" : [ "JavaScript", "SQL Server", "Python", "Ruby" ] }
- フィールド名の変更
> db.member.updateMany( {}, {$rename: {name: "lastName"}} )
- 結果
{ "age" : 27, "lastName" : "satoh" }
- 結果
- 更新の対象がなければ追加
- update と insert を組み合わせた upsert を指定する
> db.member.updateOne( {lastName: "satoh"}, {$set:{job: "engineer"}}, {upsert:true} )
- 結果
{ "age" : 27, "lastName" : "satoh", "job" : "engineer" }
- upsert を指定すると、検索条件にない場合、データが新規登録される
最後に delete の処理を試してみたところで、このコースは修了しました。
まとめ
NoSQL のうちドキュメント DB の代表格、 MongoDB を一通り操作してみました。
JavaScript のプログラムのように CRUD が書けるのは、 SQL と全く違うものでした。 JavaScript プログラマにとっては書きやすいため、かなりスピードが出せそうです。 またフィールドの追加や配列やオブジェクトをそのままストアできるのは、とてもラクなので、特に 0 → 1 のスタートアップフェーズでは強力な武器になりますね。
JavaScript に慣れている方、チームにはとてもオススメのコースでした!
label SEカレッジを詳しく知りたいという方はこちらから !!
IT専門の定額制研修 月額 28,000 円 ~/ 1社 で IT研修 制度を導入できます。
年間 670 講座をほぼ毎日開催中!!
SEプラスにしかないコンテンツや、研修サービスの運営情報を発信しています。