MongoDBのcollection基本操作をpythonで(pymongo)
pymongoによるMongoDBのcollectionに対する操作をしょっちゅう忘れるのでメモします。バージョンは以下を想定しています。基本的にはMongoDBでのshellコマンドがそのままpymongoで使用できます。
- MongoDB == 4.4.1
- pymongo == 3.10.1
検索
基本
検索時はfind()
を使用し、以下のように条件を指定します。(MongoDBのshellでも同様です)
db.collection.find({条件})
pymongoでは、条件はdict形式で指定します。name
がhoge
のドキュメントを検索するには、以下を条件に指定します。
{"name": "hoge"}
演算子の指定
mongoDBがサポートする演算子を使用すれば、複雑なクエリを実現できます。主な演算子は以下のとおりです。
演算子 | type | 概要 | mongo shellでの例 |
---|---|---|---|
$lt | Comparison | < | {age: $lt: 20}} |
$lte | Comparison | <= | {age: {$lte: 20}} |
$gt | Comparison | > | {age: {$gt: 20}} |
$gte | Comparison | >= | {age: {$gte: 20}} |
$ne | Comparison | != | {age: {$ne: 20}} |
$in | Comparison | 配列指定した値のいずれかにマッチする | {tags: {$in: [ |
$nin | Comparison | 配列指定した値のいずれにもマッチしない | {tags: {$nin: [ |
$and | Logical | 配列指定した条件のANDにマッチする | {$and: [{cond1}, {cond2} ]} |
$or | Logical | 配列指定した条件のORにマッチする | {$or: [ {cond1}, {cond2} ]} |
$exist | Element | 特定のフィールドを持つドキュメントにマッチする | {name: {$exist:true}} |
$regex | Evaluation | 指定した正規表現にマッチする | {name: {$regex: /hoge/}} |
クエリに関する他の演算子は以下の公式ドキュメントで確認できます。
上記の演算子をpymongoで使用する時は、演算子全体を文字列として指定します。例えば
AND ┳ age > 20 ┣ languageに"English"または"Japanese"を含む ┣ TOEFL というフィールドを持つ ┗ name に Tanaka を含む
のような条件で検索したいときは、.find()
の条件に以下を指定します。
# and条件のリスト cond_l = [ # age > 20 {"age": {"$gt": 20} }, # languageにEnglishかJapaneseを含む {"language": {"$in": ["English", "Japanese"]} }, # TOEFL のフィールドを持つ {"TOEFL": {"$exist": True} }, # nameにTanakaを含む('/'を使わない) {"name": {"$regex": "Tanaka"} } ] # 条件のANDを取る cond = {"$and": cond_l} db.collection.find(cond)
注意点として、pymongoで正規表現を使用する際は/
を使いません。pythonから操作する際は気を付けましょう。
更新
基本
shellでは以下が基本操作です。
db.collection.update({条件}, {更新演算子: {更新内容}})
更新演算子には多くの場合$set
が使われ、「条件」に合致するドキュメントを「更新内容」で更新します。name
がhoge
のドキュメントのage
を25
に更新するとき、pymongoでは
update({"name": "hoge"}, {"$set": {"age": 25}})
のように記述します。更新するフィールドが複数ある場合は、「更新内容」に複数条件を並列して記述できます↓
{"$set": {"name": "Suzuki", "age": 25} }
更新演算子は必ず指定してください。以下のように書いてしまうと、該当するドキュメントを「更新内容」で上書きしてしまいます。
db.collection.update({条件}, {更新内容})
主な更新演算子は以下です。
演算子 | type | 概要 | mongo shellでの例 |
---|---|---|---|
$set | Fields | 指定したフィールドに値をセットする(なければ追加する) | {$set: {age: 25}} |
$unset | Fields | 指定したフィールドを削除する | {$unset: {name: ""}} |
$pop | Array | 指定したフィールドの配列の先頭または末尾を一つ削除する | {$pop: {tags: -1}} |
$push | Array | 指定したフィールドの配列に値を追加する | {$push: {tags: "test"}} |
更新演算子の一覧は以下のページで確認できます。Arrayの操作に関する演算子は使いこなせば色々なことができそうです。
複数ドキュメントの更新
shellによる操作では、update()
はヒットした最初のドキュメントのみ更新します。これはpymongoでも同様です。複数更新するには、以下のようにoptionにmulti:true
を指定する必要があります。
db.collection.update({条件}, {$set: {更新内容}, {multi:true}}
pymongoでは以下のようにオプションを記述します。
db.collection.update({"field":"value"}, multi=True)
ただし、pymongoではupdate()
は非推奨となっています。更新ドキュメント対象の意図を明確にするために、update_one()
またはupdate_many()
の使用を推奨されています。複数更新する場合はupdate_many()
を使用しましょう。(mongoDBのshellにもupdateOne
, updateMany
があるので、そちらを使うのが無難かもしれません)
Updateメソッドに関するMongoDBのドキュメントは以下で見ることができます。
削除
基本
以下のコマンドで、条件にマッチするドキュメントの削除ができます。
db.collection.remove({条件})
name
がhoge
のドキュメントを削除する際のpymongoでのコマンドは以下になります。
db.collection.remove({"name": "hoge"})
複数ドキュメントの削除
remove()
はデフォルトで複数ドキュメントを削除するように動作します。条件にマッチした最初の一件のみ削除したい場合は、オプションとして{justOne: true}
を指定できます。
db.collection.remove({条件}, {justOne:true})
pymongoではオプションの引数はmulti
で指定します。
db.collection.remove({"field":"value"}, multi=False)
これも、削除したい件数の意図を明確にするためにdelete_one()
, delete_many()
が用意されています。(対応するmongo shellコマンドはdeleteOne()
, deleteMany()
です)特に理由がなければremove
は使わないようにしたほうが無難かもしれません。
その他使いそうなコマンド
ドキュメント追加
collectionにドキュメントを追加します。追加したいドキュメントはdict形式で指定します。
db.collection.insert({追加したいドキュメント})
件数取得
条件にマッチするドキュメントの件数を取得できます。
db.collection.find({条件}).count()
collection削除
指定したcollectionを削除します。
db.collection.drop()
collectionに対する他のshell コマンドは以下で確認できます。
pymongoのdocumentationも以下サイトで検索すると大体出てきます(めんどくさくなってきた)
まとめ
主なmongo shellコマンドとpymongoでの使用法を調べました。MongoDBの公式ドキュメントは見やすくて助かります。NoSQLから入ってしまったのでいずれはRDBMSも学びたいところです。
参考
pymongoを使った様々な検索条件(AND/OR/部分一致/範囲検索) - Qiita