pythonでMongoDBを入門しよう

#前書
初めての記事になりますので、至らぬ所も多くあると思いますがよろしくお願いします
またpythonに関する内容はある程度pythonの文法分かってる方を想定してますので、文法に関する説明は省かせていただきます

# 最初はMongo DBついて簡単な紹介
![mongo](https://techblog.gmo-ap.jp/wp-content/uploads/2015/11/mongodb-logo.png)
MongoDBはRDBMSではなく、いわゆるNoSQLと呼ばれるデータベースに分類されるものである。RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する. --Wikipediaにより

#インストール
![alt](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongodb.PNG?raw=true)
[ダウンロードリンク](https://www.mongodb.com/download-center/community)
ここでバージョンとOSを指定してダウンロード可能です
インストール終わったら実際MongoDB起動してみましょう

#サーバー立ち上げと接続
インストールられたパス内の.\bin ファイル内に入ってください
コマンドプロンプトを立ち上げて
####`C:\MongoDb\Sever\bin>mongod --dbpath C:\MongoDb\data`
このようなコマンドを打ってください
データを保存するためのpathを設定する必要があるので
予めにファイルを作っておいてください
![image.png](https://qiita-image-store.s3.amazonaws.com/0/320164/c0b6630a-670f-c73f-6b42-7ea3279d5fb9.png)
:point_up:システム環境変数にmongod 入れても大丈夫です
立ち上げ成功したら,このような画面が表示されます
![image.png](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongo3.PNG?raw=true)
では実際繋いでみましょう
ディレクトリ`.\bin`内に新しいコマンドプロンプトを立ち上げ
![image.png](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongo4.PNG?raw=true)
`mongo`を入力してください
![image.png](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongo5.PNG?raw=true)
コマンドプロンプトにこのようなコードが表示されたら接続成功です
#操作
`mongoShell`と`python`を使った操作2パターンやっていきましょう
pythonは3.*を使用します
##mongoShell
先ずデータベース何があるのか見てみます
`show dbs`をコマンドプロンプトに入力
![image.png](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongo6.PNG?raw=true)
既存データベースの一覧が見られます
新規の`test`データベースを作っていきます
`use test`を入力してください
`switched to db test`というメッセージが表示されたら成功です
では、データを入れていきます
`db.test.insert({"name":"MongoDB"})`を入力してください
`WriteResult({ "nInserted" : 1 })`が表示したら成功です
mongodbので保存されるデータは全部key ,val形式で,
pythonでいう辞書型のようなものになります
今回の場合keyは"name",valは"MongoDB"になります.

先入力したデータ見てみましょう
`db.test.find()`あるいは`db.test.findOne()`を入力してください
![image.png](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongo7.PNG?raw=true)
このように先ほど入力したデータを探し出せます
また条件指定でデータ探し出すのも可能です
`db.test.find({"name":"MongoDB"})`のように`find(条件)`を入れて上げる事で探せます
また曖昧検索も下記のような正規表現に近い文脈で実現可能
`db.test.find({title:/B$})`ここで踏み込んだ説明は省かせていただきます
もし"_id"使って探したい場合
`"_id":ObjectId("5c4542522ab09b5e5b79663d"`を全体渡す必要があります
条件付きでデータ削除する場合
 `db.test.remove({"name":"MongoDB"})`でできます
他のCRUD操作は公式ドキュメントを参考してください
[公式ドキュメント](https://docs.mongodb.com/manual/crud/)
##pythonでMongoDBを操作する
####ライブラリのインストール
pip install pymongo
[公式ドキュメント](https://api.mongodb.com/python/current/)
:point_up:ここでは皆様ある程度pythonを使用できると想定し例えば,何がpipなどの説明は省かせていただきます
####サーバーへの接続
先ずmongodbサーバー正常に作動してる状態を確認してください
pythonのファイルを作ります(ここではPyCharm使用します)
:point_up:pythonshellでも同じ動作できます またエディタもご自身慣れてるものをご使用ください
#####早速接続してみましょう
先ほどインストールしたライブラリ内の`MongoClient`を先ずインポート
![image.png](https://github.com/huanshenyi/python_Regular-expression_Crawler/blob/master/mongo8.PNG?raw=true)
接続方法基本この三つになります
1.`client_1 = MongoClient()`ホストを省き,ローカル内のサーバーへ接続に使用  
2.`client_2 = MongoClient('localhost', 27017)`
3.`client_3 = MongoClient('mongodb://localhost:27017/')` ローカル内でなければhost番号入れて接続する場合、この二つの方法使用できます
今回はローカル内での接続を試します
pythonプログラムをrunしてみてください。
そうすれば、最初立ち上げたMongoDBサーバー用のコマンドプロンプトに

```shell
2019-01-21T14:57:19.061+0900 I NETWORK  [conn17] received client metadata from 127.0.0.1:58909 conn17: { driver: { name: "PyMongo", version: "3.7.2" }, os: { type: "Windows", name: "Windows 10", architecture: "AMD64", version: "10.0.17134-SP0" }, platform: "CPython 3.7.1.final.0" }
2019-01-21T14:57:19.553+0900 I NETWORK  [conn17] end connection 127.0.0.1:58909 (8 connections now open)
```

のメッセージが確認できましたら接続成功です
`{ name: "PyMongo", version: "3.7.2" }`pymongoで接続し,使用してるpythonのバージョンも確認できます
`print(client_1.PORT)`でポート番号確認しますと`27017`が確認できるはずです
また`client_1.database_names()`で存在するDB名を一覧できます
####pythonでCRUD
###### データ挿入
Qiitaの機能良かったのでこのままコード書いていきます

```python:MongoDB.py
from pymongo import MongoClient
from datetime import datetime

class TestMongo(object):
   
     def __init__(self):
         self.clint = MongoClient()
         self.db = self.clint['test']

     def add_one(self):
        """データ挿入"""
        post = {
            'title': 'ハリネズミ',
            'content': 'ハリネズミ可愛い~',
            'created_at': datetime.now()
        }
        return self.db.test.insert_one(post)

def main():
    obj = TestMongo()
    rest = obj.add_one()
    print(rest)

if __name__ == '__main__':
    main()
```
これを実行すると`<pymongo.results.InsertOneResult object at 0x000001ABA8BD9688>`という戻り値が確認できます,今MongoDBの中を覗いてみると
![キャプチャ23242.PNG](https://qiita-image-store.s3.amazonaws.com/0/320164/767c772d-7c81-8b84-540e-839d6103bb91.png)
ちゃんとデータが入ってるはずです
ここは見やすくするために`robomongo`というソフト使用してます [リンク](https://robomongo.org/download)
また、複数のデータを挿入する場合

```python:MongoDB2.py
 post=[
            {'title': 'カワウソ', 'content': 'カワウソ可愛い~', 'created_at': datetime.now()},
            {'title': 'ハムスター', 'content': 'ハムスター可愛い~', 'created_at': datetime.now()},
            {'title': 'チンチラ', 'content': 'チンチラ可愛い~', 'created_at': datetime.now()}
        ]
        return self.db.test.insert_many(post)
```
の感じでできます
###### データ読み取る
MongoDB.py内にget_one関数を追加します

```python:MongoDB3.py
    def get_one(self):
        return self.db.test.find_one()

def main():
    obj = TestMongo()
    rest = obj.get_one()
    print(rest)
```

起動してみると
`{'_id': ObjectId('5c456689736d313bf8a936f1'), 'title': 'ハリネズミ', 'content': 'ハリネズミ可愛い~', 'created_at': datetime.datetime(2019, 1, 21, 15, 28, 25, 860000)}`
最初入れたデータが取得できます
すべてのデータを取得する場合は`self.db.test.find()`を使用します
mongoShellでの使い方結構似てますよね

また_idを使ってデータの読み取りを行う際に少し手順が増えます
`from bson.objectid import ObjectId`を先ずインポートして

```python:MongoDB4.py
    """新しい関数を定義"""
    def get_from_oid(self,oid):
        return self.db.test.find_one({'_id':ObjectId(oid)})
def main():
    obj = TestMongo()
                            """_idを渡す"""
    rest = obj.get_from_oid('5c456bf0736d313a7c0afb80')
    print(rest)
```
これで取得できます
`{'_id': ObjectId('5c456bf0736d313a7c0afb80'), 'title': 'チンチラ', 'content': 'チンチラ可愛い~', 'created_at': datetime.datetime(2019, 1, 21, 15, 51, 28, 253000)}`

###### データ修正
```python:MongoDB4.py

    def update(self):
        rest = self.db.test.update_one({"title": "ハムスター"}, {"$set": {"content": "カワウソうるさい"}})
        return rest
def main():
    obj = TestMongo()
    rest = obj.update()
    print(rest.matched_count)
```
`matched_count`を渡して起動すれば1という結果が出てきます、マッチしたデータの数です
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/320164/01cbc55a-0d61-1461-cfd0-950dec4b6b99.png)
データ修正されたことも確認できます
複数修正する場合は

```python:MongoDB5.py

    def update(self):
        """複数修正"""
        rest = self.db.test.update_many({}, {'$set': {"created_at": datetime.now()}})
        return rest

def main():
    obj = TestMongo()
    rest = obj.update()
    print(rest.matched_count)
```
4という数字が確認できます、すべてのデータの`"created_at"`が修正されました

###### データ削除
```python:MongoDB6.py
    def delete(self):
        """マッチした最初のデータを削除"""
        rest = self.db.test.delete_one({"title":"ハムスター"})
        return rest

def main():
    obj = TestMongo()
    rest = obj.delete()
```
要領基本同じです，条件を渡して削除
複数削除する場合
`self.db.test.delete_many({"title":"ハムスター"})`
oneをmanyに変えればできます


## 最後
:relaxed:最初のブログになりますので分かりやすく書いてるつもりではありますが
至らぬところはまた多くあると思います、ご指摘のほどよろしくお願いいたします。
今後も何か書いていきたいと思います

# 続編
[PythonでMongoDBのODMを使用しよう](https://qiita.com/Syoitu/items/5edf9b422b17699093ac)