Help us understand the problem. What is going on with this article?

MongoDB入門してみた(1)CRUD操作

More than 3 years have passed since last update.

特にきちんとした脈絡もなく記述。
ほとんど自分向けの備忘録なので雑に書いてます。

純正のMongoDBではなく、Percona Server for mongoDBを利用している点には注意

目的

mongoDBの基本的な操作方法(CRUD)を学ぶ

MongoDBの導入

ここではあえて純正のMongoDBではなく、
Percona server for MongoDBを利用する。
セットアップ手順についても公式のDockerイメージを導入することで
利用を行う。

PerconaServerの導入
sudo docker pull percona/percona-server-mongodb
sudo docker run -d --name percona -p 3306:3306 percona/percona-server-mongodb

これで起動完了。

MongoDBの操作

MongoDBへの接続

MongoDBへの接続。
sudo docker exec -it percona /bin/bash
mongo

これで接続はOK。

ドキュメントへのCRUD

ドキュメントの作成(Create)

利用するデータベースの指定
mongo
use foo

mongoコマンドでmongo shellに入って利用するdb名を指定する。

insertによるドキュメント作成例
db.sample.insert({name: "test"})
特定コレクション内のドキュメント数のカウント
db.コレクション名.count()
1

ドキュメントの読み込み(Read)

findでは一定数(デフォルトでは20件)分のカーソルを返す。

読み込み
db.コレクション名.find()
{ "_id" : ObjectId("5867deb238a8218f8be46c55"), "name" : "test" }

findOneでは単一のドキュメントを返す

読み込みその2
db.コレクション名.findOne()
{ "_id" : ObjectId("5867deb238a8218f8be46c55"), "name" : "test" }
find,findOneの記述
db.コレクション名.find(検索条件, 射影)
db.コレクション名.findOne(検索条件, 射影)

条件絞り込みのオペレータ

範囲の確認

検索条件において一致だけではなく、数値の範囲を指定する場合に利用

オペレータ 意味
$gt 〜より大きい(Greater Than)
$gte 〜以上(Greater Than or Equal
$lt 〜未満(Less Than)
$lte 〜以下(Less Than or Equal
フィールドの存在の有無の確認($exists)
$existsオペレータ
db.コレクション名.find({フィールド名: {$exists: true}})

特定のフィールド名が存在するドキュメントを表示

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

ドキュメントの更新。
var doc1 = db.コレクション名.findOne()
doc1.フィールド名 = 更新値

オペレータによる操作

ドキュメントの値(特に数値)を更新する際には、
オペレータを利用する。

オペレータ 内容
$set 値の設定
$inc 値の加算(減算)
$mul 値の乗算(除算)
$unset 値の削除
$setオペレータによるフィールドの更新・追加
$setオペレータ
db.コレクション名.update({検索条件}, {$set: {キー: 値, ... })

数値情報を更新する際にはsetオペレータよりもincオペレータのほうが良い?

$incオペレータによるフィールド値のアトミックな更新(加算)
$incオペレータ
db.コレクション名.update({検索条件}, {$inc: {キー: 加算値, ...}})

既存のキーに対応する値に加える操作についてアトミックに記述することができる。

$mulオペレータによるフィールド値のアトミックな更新(乗算)
$mulオペレータ
db.コレクション名.update({検索条件}, {$mul: {キー: 乗算値, ...}})
$unsetオペレータによるフィールドの削除
$unsetオペレータ
db.コレクション名.update({検索条件}, {$unset: {キー: 値, ...}})

$unset内部で指定している値は意味がない。

配列の操作

単独の値だけではなく配列の操作も必要となる

配列の操作オペレータは以下の通り

オペレータ 意味
$push 要素の末尾に要素を一つ追加
$pop 要素の一つを削除
$pull 指定条件にマッチする要素を一つ削除
$pullAll 指定条件にマッチする要素すべて削除
$pushによる要素の追加
$push
db.col1.insert({ary: [0, 1, 2, 3, 2, 1, 0]})
db.col1.update({ary: {$exists: true}}, {$push: {ary: 10}})
$popによる値の削除
$pop
db.col1.update({ary: {$exists: true}}, {$pop: {ary: -1}})

$popで"-1"を指定すると配列の先頭の値が削除される。
それ以外の値を指定すると配列末尾の値が削除される。

$pullによる一括削除

条件にマッチする要素を削除する。

$pull
db.col1.update({ary: {$exists: true}}, {$pull: {ary: {$gte: 2}}})

aryに含まれる値が2より大きい場合に削除
がっちまん

$pullAllによる一括削除

条件に一致する要素を削除する。

$pullAllによる削除例
db.col1.update({ary: {$exists: true}}, {$pullAll: {ary: [1,2]}})

aryに含まれる値が1または2の場合に削除

特殊な更新(save, upsert)

ドキュメントの状態によって挙動が変わる場合としてsaveとupsertの2つが存在

save
save
db.コレクション名.save(挿入・更新したいドキュメント)

挿入・更新したいドキュメントの_idフィールドによって動作が変わる。

  1. _idが既存ドキュメントと一致 => update
  2. idが既存ドキュメントと一致しない(またはidがない) => insert
upsert
upsert内容
db.コレクション名.update(検索条件, 挿入or更新したいドキュメント内容, {upsert: true})

複数ドキュメントの一括アップデート(multi)

一括アップデート
db.コレクション名.update(検索条件, アップデート内容, {multi:true})

検索と修正を一括で行う(findAndModify)

findAndModify
db.コレクション名.findAndModify(
    query: 検索条件,
    sort: ソート条件,
    remove: 削除指定,
    update: アップデート指定,
    new: 関数の返り値指定,
    fields: 返り値の射影(sqlのselectに相当),
    bypassDocumentValidation: ドキュメントのバリデーション有無,
    writeConcern: 書き込み条件
)

削除(Delete)

ドキュメントの削除

ドキュメントの削除(remove)
db.コレクション名.remove(検索条件)

コレクションの削除

コレクションの削除(drop)
db.コレクション名.drop()

データベースの削除

データベースの削除(dropDatabase())
use 削除したいデータベース名
db.dropDatabase()

参考文献

初めてのMongoDB 小笠原 徳彦著, 工学社刊

RyoMa_0923
インフラエンジニア? 記事の内容、およびそのなかで述べられている見解は個人のものであり、所属組織とは関係ありません。また、記事内容の正しさは必ずしも保証されるものではありません。
https://note.com/ryoma_0923
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした