Python
MongoDB
DB
nosql
pymongo

NoSQLデータベース「MongoDB」をPythonで利用する~pymongoの基本的な使い方まとめ~

MongoDBをpythonで使うためのライブラリ、pymongo。
僭越ながら基本的な使い方をまとめてみました。
間違っていたらご指摘ください。随時追記します。
作成段階ではver3.5.1です。

英語がある程度わかる人は以下を読んだ方が早いです。
http://api.mongodb.com/python/

本記事概要

基本的なRDBでいうselect,insertのやり方を紹介します。
MongoDBで基本的なデータ構造については以下を参照
https://qiita.com/yuji0602/items/c55e2cb75376fd565b4e

インストール・アップグレード(pipを使用)

インストール

python -m pip install pymongo

バージョンを指定する場合は以下

python -m pip install pymongo==3.1.1

アップデート

python -m pip install --upgrade pymongo

準備

MongoDBへの命令(クエリ)を担当する「MongoClient」さんをインポートしておきます
自分のローカル端末にインストールしたMongoDBを使いたい場合、以下のようにMongoClientを用意します。
第一引数にはアドレス、第二引数にはポート番号を設定します。MongoDBのデフォルトのポート番号は27017です。

from pymongo import MongoClient
client = MongoClient('localhost', 27017)

URLで指定することもできます。

client = MongoClient('mongodb://localhost:27017/')

データベースの呼び出し

MongoClientを使って、データベースを呼び出します。
以下ではMongoDBの中の"test_database"という名前のデータベースを呼び出しています。

db = client.test_database

MongoDBの中に"test_database"という名前のデータベースがなかった場合は、自動的に作成されます。

以下のような書き方でも同様です。
for文等で名前を変えながら参照したい場合、楽です。

db = client['test-database']

コレクションの呼び出し

MongoClientを使って、データベースの中にあるコレクションを呼び出します。
コレクションとはRDBでいうテーブルに該当します。
データベースと同様、コレクションがなかった場合は自動で作成されます。

collection = db.test_collection

データベースと同様に以下の書き方でも可能。

collection = db['test-collection']

ドキュメントについて

MongoDBのデータは以下のようなJSON形式で格納されています。
JSONについては以下を参照
https://thinkit.co.jp/article/70/1

import datetime
post = {"author": "Mike",
        "text": "My first blog post!",
        "tags": ["mongodb", "python", "pymongo"],
        "date": datetime.datetime.utcnow()}

RDBでいう行がドキュメント、列はフィールドと呼ばれます。
上記でいうと「post」自体が【ドキュメント】。
「post」の中の"author"や"text"などが【フィールド】です。

コレクションにドキュメントを入れる(insert)

事前に呼び出したコレクション「collection」に上記で用意した「post」を挿入する
返り値は「InsertOneResult」というpymongo内で定義されているインスタンスが返されます。

#idは自動で一意に振り分けられる
result1 = collection.insert_one(post)

複数のドキュメントを格納したい場合は「insert_many()」を使う

new_posts = [{"author": "Mike",
              "text": "Another post!",
              "tags": ["bulk", "insert"],
              "date": datetime.datetime(2009, 11, 12, 11, 14)},
             {"author": "Eliot",
              "title": "MongoDB is fun",
              "text": "and pretty easy too!",
              "date": datetime.datetime(2009, 11, 10, 10, 45)}]
result2 = collection.insert_many(new_posts)

コレクション内のドキュメントを参照する(select)

findメソッドで参照します。

ドキュメントを一つ参照したい場合

find_one()メソッドを使用します。

print(collection.find_one())

以下出力。find_one()の括弧内で参照したいドキュメントを指定しますが、
何も指定しないとコレクション内の初めのドキュメントを参照します。

#出力
{u'_id': ObjectId('...'),
 u'author': u'Mike',
 u'date': datetime.datetime(...),
 u'tags': [u'mongodb', u'python', u'pymongo'],
 u'text': u'My first blog post!'}

例えば、フィールド"author"が"Mike"のドキュメントを参照したい場合は以下の通り。

collection.find_one({"author": "Mike"})

ドキュメントを複数参照したい場合

find()メソッドを使用します。
pymongo内で定義されているCursorというインスタンスを返します。

for post in collection.find():
    print(post)

以下、出力

{u'_id': ObjectId('...'),
 u'author': u'Mike',
 u'date': datetime.datetime(...),
 u'tags': [u'mongodb', u'python', u'pymongo'],
 u'text': u'My first blog post!'}
{u'_id': ObjectId('...'),
 u'author': u'Mike',
 u'date': datetime.datetime(...),
 u'tags': [u'bulk', u'insert'],
 u'text': u'Another post!'}
{u'_id': ObjectId('...'),
 u'author': u'Eliot',
 u'date': datetime.datetime(...),
 u'text': u'and pretty easy too!',
 u'title': u'MongoDB is fun'}