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

MongoDB 4.0のCentOS7へのインストールと基本操作

More than 1 year has passed since last update.

ドキュメント指向のNoSQLとして人気があり、Web系のログ蓄積等で耳にするMongoDBを、こちらを参考に触ってみたのでまとめます。

MongoDBの主な特徴

  • スキーマレス(データ構造の事前定義が不要)
  • JOIN、トランザクションのサポートはない
  • 水平分散による拡張性

MongDBのインストール

vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc

yum install mongodb-org
systemctl start mongod
systemctl enable mongod

デフォルトは27017でListen

[root@localhost ~]# lsof -i :27017
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  10642 mongod   10u  IPv4  49590      0t0  TCP localhost:27017 (LISTEN)

firewall-cmd --add-port=27017/tcp --zone=public --permanent
firewall-cmd --reload

Mongoシェルの起動

コンソールでmongoと入力

[root@localhost ~]# mongo
MongoDB shell version v4.0.3
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("c94e5484-bc07-448d-a696-552294043074") }
MongoDB server version: 4.0.3
・・・・

test dbを作成(+接続も同時に実施される)

> use test
switched to db test

DBの状態を確認

> db.stats()
{
        "db" : "test",
        "collections" : 0,
        "views" : 0,
        "objects" : 0,
        "avgObjSize" : 0,
        "dataSize" : 0,
        "storageSize" : 0,
        "numExtents" : 0,
        "indexes" : 0,
        "indexSize" : 0,
        "fileSize" : 0,
        "fsUsedSize" : 0,
        "fsTotalSize" : 0,
        "ok" : 1
}

テストデータの挿入

db.user.insert({name:'mr.a', age:10, gender:'m', hobbies:['programming']});
db.user.insert({name:'mr.b', age:20, gender:'m', hobbies:['vi']});
db.user.insert({name:'ms.c', age:30, gender:'f', hobbies:['programming', 'vi']});
db.user.insert({name:'ms.d', age:40, gender:'f', hobbies:['cooking']});

データの確認: findがSQLのSELECT

> db.user.find()
{ "_id" : ObjectId("5bd6be298d280c3a544ebce6"), "name" : "mr.a", "age" : 10, "gender" : "m", "hobbies" : [ "programming" ] }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce7"), "name" : "mr.b", "age" : 20, "gender" : "m", "hobbies" : [ "vi" ] }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce8"), "name" : "ms.c", "age" : 30, "gender" : "f", "hobbies" : [ "programming", "vi" ] }
{ "_id" : ObjectId("5bd6be2b8d280c3a544ebce9"), "name" : "ms.d", "age" : 40, "gender" : "f", "hobbies" : [ "cooking" ] }
>

RDBとMongoDBの用語比較

RDB   MongoDB
データベース データベース
コレクション
行(レコード) ドキュメント
フィールド

条件演算

クエリセレクタ:{フィールド名:値}で条件を渡す
年齢が20歳以上の男性を抽出  比較演算子

> db.user.find({age:{$gte:20}, gender:'m'})
{ "_id" : ObjectId("5bd6be298d280c3a544ebce7"), "name" : "mr.b", "age" : 20, "gender" : "m", "hobbies" : [ "vi" ] }

配列

配列もその他のフィールド(列)と同様に検索可能

>  db.user.find({hobbies:'cooking'})
{ "_id" : ObjectId("5bd6be2b8d280c3a544ebce9"), "name" : "ms.d", "age" : 40, "gender" : "f", "hobbies" : [ "cooking" ] }

取得フィールド(列)の指定

SELECT 列名相当は、findの第2引数に取得するフィールド名を指定
{フィールド名:0}以外の数字で表示、{フィールド名:0}で非表示

> db.user.find({}, {age:0})
{ "_id" : ObjectId("5bd6be298d280c3a544ebce6"), "name" : "mr.a", "gender" : "m", "hobbies" : [ "programming" ] }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce7"), "name" : "mr.b", "gender" : "m", "hobbies" : [ "vi" ] }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce8"), "name" : "ms.c", "gender" : "f", "hobbies" : [ "programming", "vi" ] }
{ "_id" : ObjectId("5bd6be2b8d280c3a544ebce9"), "name" : "ms.d", "gender" : "f", "hobbies" : [ "cooking" ] }
> db.user.find({}, {age:1})
{ "_id" : ObjectId("5bd6be298d280c3a544ebce6"), "age" : 10 }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce7"), "age" : 20 }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce8"), "age" : 30 }
{ "_id" : ObjectId("5bd6be2b8d280c3a544ebce9"), "age" : 40 }

Update

下記で更新可能
db.コレクション名.update({検索条件}, {$set:{更新内容}})
※$setがないと、検索条件列が更新内容の値でUpdateされるので注意

> db.user.find({name:"mr.a"})
{ "_id" : ObjectId("5bd6be298d280c3a544ebce6"), "name" : "mr.a", "age" : 10, "gender" : "m", "hobbies" : [ "programming" ] }

>  db.user.update({name:'mr.a'}, {$set:{gender:'X'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find({name:"mr.a"})
{ "_id" : ObjectId("5bd6be298d280c3a544ebce6"), "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }

特定ドキュメント(行)にフィールド(列)追加も可能

存在しないフィールドを更新し、名前がmr.bの人のレコードに、hoge:111という新しいフィールドを追加

> db.user.update({name:'mr.b'}, {$set:{hoge:111}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5bd6be298d280c3a544ebce6"), "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }
{ "_id" : ObjectId("5bd6be298d280c3a544ebce7"), "name" : "mr.b", "age" : 20, "gender" : "m", "hobbies" : [ "vi" ], "hoge" : 111 }

Upsert

データが存在しなければINSERT、存在すればUPDATE
存在しない=コレクション(表)が無い場合と、該当ドキュメント(行)が無い場合
共になければ自動的に作成、あればUPDATEされる

例)db.counter.update( {type:'success'} ,{$inc:{count:1}}, true)
$incは、対象の値を増分

> db.counter.update( {type:'error'} ,{$inc:{count:1}}, true)
> db.counter.update( {type:'error'} ,{$inc:{count:1}}, true)
> db.counter.update( {type:'error'} ,{$inc:{count:1}}, true)
> db.counter.update( {type:'success'} ,{$inc:{count:1}}, true)

> db.counter.find()
{ "_id" : ObjectId("5bd7b8b5d6949f96aeb75451"), "type" : "error", "count" : 3 }
{ "_id" : ObjectId("5bd7b8fcd6949f96aeb7545a"), "type" : "success", "count" : 1 }

複数件同時更新

db.user.update({}, {$set:{gender:'X'}},false,true)
※第三引数:upsert (false:存在しないレコードは更新しない)
第四引数:trueにして、複数件を更新

> db.user.find({},{_id:0})
{ "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }
{ "name" : "mr.b", "age" : 20, "gender" : "m", "hobbies" : [ "vi" ], "hoge" : 111 }
{ "name" : "ms.c", "age" : 30, "gender" : "f", "hobbies" : [ "programming", "vi" ] }
{ "name" : "ms.d", "age" : 40, "gender" : "f", "hobbies" : [ "cooking" ] }

> db.user.update({}, {$set:{gender:'X'}}, false, true)
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 3 })

> db.user.find({},{_id:0})
{ "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }
{ "name" : "mr.b", "age" : 20, "gender" : "X", "hobbies" : [ "vi" ], "hoge" : 111 }
{ "name" : "ms.c", "age" : 30, "gender" : "X", "hobbies" : [ "programming", "vi" ] }
{ "name" : "ms.d", "age" : 40, "gender" : "X", "hobbies" : [ "cooking" ] }

Remove

ドキュメント(行)削除
db.user.remove()

> db.user.remove({age:{$gte:30}})
WriteResult({ "nRemoved" : 2 })

> db.user.find({},{_id:0})
{ "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }
{ "name" : "mr.b", "age" : 20, "gender" : "X", "hobbies" : [ "vi" ], "hoge" : 111 }

Sort,Count

sort: {フィールド:1(昇順)}、{フィールド:ー1(降順)}
count: count()

> db.user.find({},{_id:0}).sort({age:1})
{ "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }
{ "name" : "mr.b", "age" : 20, "gender" : "X", "hobbies" : [ "vi" ], "hoge" : 111 }
> db.user.find({},{_id:0}).sort({age:-1})
{ "name" : "mr.b", "age" : 20, "gender" : "X", "hobbies" : [ "vi" ], "hoge" : 111 }
{ "name" : "mr.a", "age" : 10, "gender" : "X", "hobbies" : [ "programming" ] }

> db.user.find({}).count()
2
m-eno
k8s、RDB/NoSQL周辺
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
ユーザーは見つかりませんでした