79
76

More than 3 years have passed since last update.

pythonでMongoDBを入門しよう

Last updated at Posted at 2019-01-21

前書

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

最初はMongo DBついて簡単な紹介

mongo
MongoDBはRDBMSではなく、いわゆるNoSQLと呼ばれるデータベースに分類されるものである。RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する. --Wikipediaにより

インストール

alt
ダウンロードリンク
ここでバージョンとOSを指定してダウンロード可能です
インストール終わったら実際MongoDB起動してみましょう

サーバー立ち上げと接続

インストールられたパス内の.\bin ファイル内に入ってください
コマンドプロンプトを立ち上げて

C:\MongoDb\Sever\bin>mongod --dbpath C:\MongoDb\data

このようなコマンドを打ってください
データを保存するためのpathを設定する必要があるので
予めにファイルを作っておいてください
image.png
:point_up:システム環境変数にmongod 入れても大丈夫です
立ち上げ成功したら,このような画面が表示されます
image.png
では実際繋いでみましょう
ディレクトリ.\bin内に新しいコマンドプロンプトを立ち上げ
image.png
mongoを入力してください
image.png
コマンドプロンプトにこのようなコードが表示されたら接続成功です

操作

mongoShellpythonを使った操作2パターンやっていきましょう
pythonは3.*を使用します

mongoShell

先ずデータベース何があるのか見てみます
show dbsをコマンドプロンプトに入力
image.png
既存データベースの一覧が見られます
新規の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
このように先ほど入力したデータを探し出せます
また条件指定でデータ探し出すのも可能です
db.test.find({"name":"MongoDB"})のようにfind(条件)を入れて上げる事で探せます
また曖昧検索も下記のような正規表現に近い文脈で実現可能
db.test.find({title:/B$})ここで踏み込んだ説明は省かせていただきます
もし"_id"使って探したい場合
"_id":ObjectId("5c4542522ab09b5e5b79663d"を全体渡す必要があります
条件付きでデータ削除する場合
db.test.remove({"name":"MongoDB"})でできます
他のCRUD操作は公式ドキュメントを参考してください
公式ドキュメント

pythonでMongoDBを操作する

ライブラリのインストール

pip install pymongo
公式ドキュメント
:point_up:ここでは皆様ある程度pythonを使用できると想定し例えば,何がpipなどの説明は省かせていただきます

サーバーへの接続

先ずmongodbサーバー正常に作動してる状態を確認してください
pythonのファイルを作ります(ここではPyCharm使用します)
:point_up:pythonshellでも同じ動作できます またエディタもご自身慣れてるものをご使用ください

早速接続してみましょう

先ほどインストールしたライブラリ内のMongoClientを先ずインポート
image.png
接続方法基本この三つになります
1.client_1 = MongoClient()ホストを省き,ローカル内のサーバーへ接続に使用

2.client_2 = MongoClient('localhost', 27017)
3.client_3 = MongoClient('mongodb://localhost:27017/') ローカル内でなければhost番号入れて接続する場合、この二つの方法使用できます
今回はローカル内での接続を試します
pythonプログラムをrunしてみてください。
そうすれば、最初立ち上げたMongoDBサーバー用のコマンドプロンプトに

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の機能良かったのでこのままコード書いていきます

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
ちゃんとデータが入ってるはずです
ここは見やすくするためにrobomongoというソフト使用してます リンク
また、複数のデータを挿入する場合

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関数を追加します

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を先ずインポートして

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)}

データ修正
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
データ修正されたことも確認できます
複数修正する場合は

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"が修正されました

データ削除
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を使用しよう

79
76
3

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
79
76