Symfoware

Symfowareについての考察blog

MongoDB PyMongo 2.7.1 findでandやor、$gt,$ltを使用する

MongoDBで検索するとき、andやorで条件が指定できるか調べてみました。
サンプルはPyMongo 2.7.1を使用したプログラムです。


テストデータ



こんなテストデータを用意します。


'user':'symfo', 'values':{'key1':'v1'}, 'tags' : ['dog', 'cat'], 'number' : 1
'user':'mongo', 'values':{'key1':'v2'}, 'tags' : ['cat'], 'number' : 2
'user':'mongo', 'values':{'key1':'v3'}, 'tags' : ['mouse', 'cat', 'dog'], 'number' : 3
'user':'riak', 'values':{'key1':'v4'}, 'tags' : [], 'number' : 4




登録に使用したプログラムは以下のとおり。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. col.insert({'user':'symfo', 'values':{'key1':'v1'}, 'tags' : ['dog', 'cat'], 'number' : 1})
  9. col.insert({'user':'mongo', 'values':{'key1':'v2'}, 'tags' : ['cat'], 'number' : 2})
  10. col.insert({'user':'mongo', 'values':{'key1':'v3'}, 'tags' : ['mouse', 'cat', 'dog'], 'number' : 3})
  11. col.insert({'user':'riak', 'values':{'key1':'v4'}, 'tags' : [], 'number' : 4})







and条件指定



tagsに「dog」と「cat」を持つドキュメントを検索します。
http://docs.mongodb.org/manual/reference/operator/query/and/

findに「$and」を指定すれば良いようです。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # tagsに「dog」と「cat」があるドキュメントを検索
  9. ret = col.find({ '$and' : [{'tags': 'dog'}, {'tags': 'cat'}]})
  10. for doc in ret:
  11.     print(doc)





想定通りの結果が得られました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab309f'), u'values': {u'key1': u'v1'}, u'number': 1, u'tags': [u'dog', u'cat'], u'user': u'symfo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}








or条件指定



tagsに「dog」または「cat」を持つドキュメントを検索します。
http://docs.mongodb.org/manual/reference/operator/query/or/

findに「$or」を指定すれば良いようです。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # tagsに「dog」または「cat」があるドキュメントを検索
  9. ret = col.find({ '$or' : [{'tags': 'dog'}, {'tags': 'cat'}]})
  10. for doc in ret:
  11.     print(doc)





3つのドキュメントが抽出出来ました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab309f'), u'values': {u'key1': u'v1'}, u'number': 1, u'tags': [u'dog', u'cat'], u'user': u'symfo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}







指定値より大きい値



numberが2より大きい値を検索してみます。
条件に「$gt」を指定すればOK。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberが2より大きいドキュメント
  9. ret = col.find({ 'number' : {'$gt' : 2}})
  10. for doc in ret:
  11.     print(doc)




numberが「3」と「4」のドキュメントが取得出来ました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a2'), u'values': {u'key1': u'v4'}, u'number': 4, u'tags': [], u'user': u'riak'}







指定値を含み大きい値



numberが2以上のドキュメントを検索してみます。
条件に「$gte」を指定してやります。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberが2以上のドキュメント
  9. ret = col.find({ 'number' : {'$gte' : 2}})
  10. for doc in ret:
  11.     print(doc)





numberが2,3,4のドキュメントが取得出来ました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a2'), u'values': {u'key1': u'v4'}, u'number': 4, u'tags': [], u'user': u'riak'}







指定値より小さい値



numberが3未満のドキュメントを検索します。
条件に「$lt」を指定。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberが3未満のドキュメント
  9. ret = col.find({ 'number' : {'$lt' : 3}})
  10. for doc in ret:
  11.     print(doc)





numberが「1」と「2」のドキュメントが取得出来ました。


f0a24079ab30a2'), u'values': {u'key1': u'v4'}, u'number': 4, u'tags': [], u'user': u'riak'}
baranche@atropos:~/dev/python$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab309f'), u'values': {u'key1': u'v1'}, u'number': 1, u'tags': [u'dog', u'cat'], u'user': u'symfo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}







指定値以下の値



numberが3以下のドキュメントを検索します。
条件に「$lte」を指定。



  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberが3以下のドキュメント
  9. ret = col.find({ 'number' : {'$lte' : 3}})
  10. for doc in ret:
  11.     print(doc)





numberが1,2,3のドキュメントが取得出来ました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab309f'), u'values': {u'key1': u'v1'}, u'number': 1, u'tags': [u'dog', u'cat'], u'user': u'symfo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}







範囲指定



numberが2以上、3以下のドキュメントを検索します。
条件を並べて記載してやればOK。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberが2以上3以下のドキュメント
  9. ret = col.find({ 'number' : {'$gte' :2, '$lte' : 3}})
  10. for doc in ret:
  11.     print(doc)





狙い通り、numberが「2」と「3」のドキュメントが取得出来ました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}







辞書型の値を検索



ドキュメントのvaluesには、辞書型のデータを保存しています。
「key1」のvalueが「v2」の値を検索してみます。

フィールドの指定を「values.key1」としてやれば検索できます。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # valuesのkey1が「v2」のデータ
  9. ret = col.find({ 'values.key1' : 'v2'})
  10. for doc in ret:
  11.     print(doc)





ちゃんと1件取得出来ました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}







ソート



せっかくなので、ソートも見てみます。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberでソート
  9. ret = col.find().sort('number')
  10. for doc in ret:
  11.     print(doc)




number順にソートされます。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab309f'), u'values': {u'key1': u'v1'}, u'number': 1, u'tags': [u'dog', u'cat'], u'user': u'symfo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a2'), u'values': {u'key1': u'v4'}, u'number': 4, u'tags': [], u'user': u'riak'}





逆順にするには、pymongo.DESCENDINGを指定します。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. # MongoDBに接続
  4. client = pymongo.MongoClient('192.168.1.110', 27017)
  5. db = client.mongo_test
  6. # test_collectionを取得
  7. col = db.test_collection
  8. # numberでソート
  9. ret = col.find().sort('number', pymongo.DESCENDING)
  10. for doc in ret:
  11.     print(doc)





逆順になりました。


$ python sample.py
{u'_id': ObjectId('53d4c25804f0a24079ab30a2'), u'values': {u'key1': u'v4'}, u'number': 4, u'tags': [], u'user': u'riak'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a1'), u'values': {u'key1': u'v3'}, u'number': 3, u'tags': [u'mouse', u'cat', u'dog'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab30a0'), u'values': {u'key1': u'v2'}, u'number': 2, u'tags': [u'cat'], u'user': u'mongo'}
{u'_id': ObjectId('53d4c25804f0a24079ab309f'), u'values': {u'key1': u'v1'}, u'number': 1, u'tags': [u'dog', u'cat'], u'user': u'symfo'}




複合ソートなども実行可能です。
詳細はこちらのドキュメントのsortの項目参照。
cursor – Tools for iterating over MongoDB query results
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2014/07/27(日) 18:41:49|
  2. MongoDB
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<PHPからMongoDB 2.0.6 に接続する(PHP MongoDB Driver) | ホーム | MongoDB PyMongo 2.7.1でMap,Reduceのサンプル>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1436-693b0ee1
この記事にトラックバックする(FC2ブログユーザー)