1
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?

More than 3 years have passed since last update.

はじめてのmongodb

Last updated at Posted at 2020-06-11

起動

dockerでmongodbと、データビューアーのmongo-express2つを起動させます。

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: example

https://hub.docker.com/_/mongo

起動

docker-compose up -d

mongodbとmongo expressの2コンテナが起動します

# docker ps | grep mongo
b8f3154dda29        mongo-express                               "tini -- /docker-ent…"   34 minutes ago      Up 33 minutes       0.0.0.0:8082->8081/tcp           mongo_mongo-express_1
06e8e28840bb        mongo                                       "docker-entrypoint.s…"   35 minutes ago      Up 33 minutes       27017/tcp                        mongo_mongo_1

mongo-express

mongo-expressは こんなurlで見れる
http://localhost:8081/

こんな感じでドキュメントをブラウザから閲覧可能です(データはこの記事の↓の方でinsertしたものです)
image.png

csvに書き出すの便利そう。
image.png

データの変更もできます! 素敵だ。
image.png

CLI接続

# コンテナに入る
docker exec -it mongo_mongo_1 bash

# cli起動
root@06e8e28840bb:/# mongo -u root -p example
...
...
...
>

接続できました。username/passwordは MONGO_INITDB_ROOT_USERNAME/PASSWORD でセットしたものです。

使ってみる

神記事をなぞって、大事なところを抜き出してみます。

MongoDB超入門
https://qiita.com/saba1024/items/f2ad56f2a3ba7aaf8521

なんとびっくり、databaseの作成は超簡単

> use study

createじゃないんかい! useだけで作られる。素敵!!

データ入れながらselectしてみます

> db.stats()

# records 登録
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']});

# select * from study
> db.user.find()

# where
 db.user.find( {name:'ms.c'} )

配列(not dict) は文字列のように検索できる
> db.user.find({hobbies:'programming'})
{ "_id" : ObjectId("5ee1a837b84ea8cc6e82073f"), "name" : "ms.c", "age" : 30, "gender" : "f", "hobbies" : [ "programming", "vi" ] }

update文

MongoDBのupdateは、第2引数で渡した内容で上書き保存します。
コレは罠です。非常に危険な罠です。

これが
{ "name" : "mr.a", "age" : 10, "gender" : "m", "hobbies" : [ "programming" ] }

updateすると
db.user.update({name:'mr.a'}, {gender:'X'})

こうなっちゃう
{ "gender" : "X" }

NoSQLあるある。

実はこれ、mr.aさんの性別を更新したというよりも、名前がmr.aというドキュメントをgender:Xというドキュメントで上書きしたということになります。

上書きというより置き換えた感じ。

じゃあどうするんだよ。。。という話ですが、そのために、$setという修飾子を利用する必要があります。
本来は、$setを使って以下のようにする必要があったわけです。

> db.user.update({name:'mr.a'}, {$set:{gender:'X'}})

elasticsearchよりは簡単かも。NoSQL系はみんなこうなのかな。updateめんどくて嫌になっちゃうね。

で、このupdateにも罠がある。

コレだと、MongoDBが最初に見つけた1件のみしか更新されません。
同時に2件以上の該当レコードを一気に更新するには、第4引数にtrueを渡してあげる必要があります。

> db.user.update({}, {$set:{gender:'X'}}, false, true)

初見殺しすぎる・・・

upsert

upsert句は存在せず、updateの第3引数をtrueという残念な仕様らしい。あるだけいいけど

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

カラム追加

今日知りたかったのはここ。elasticsearchみたいにらくーにカラム追加できるのかってとこ。結論:elasticsearchよりさらに楽!

結構重要な点だと思いますが、MongoDBでは、RDBMSと違って簡単にフィールド(カラム、列)の追加ができます。
というのも、コレクション(テーブル)自体にフィールド情報が定義されているわけではなく、あくまでドキュメント(レコード、行)単位にフィールド情報が保持されているためです。

ん??

ドキュメント(レコード、行)単位にフィールド情報が保持されているためです。
ドキュメント(レコード、行)単位にフィールド情報が保持されているためです。
ドキュメント(レコード、行)単位にフィールド情報が保持されているためです。

マジカ!!!! そもそもカラムという考え方がないのか。全レコード独立してるのか。すげぇ!!!!!

勉強になりました!!使ってみよう!

1
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
1
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?