Symfoware

Symfowareについての考察blog

MongoDB PyMongo 2.7.1でMap,Reduceのサンプル

MongoDBのようなドキュメントのデータベースといえば、
Map,Reduceの機能がウリのはず。

PyMongoでPythonからMap,Reduceの機能を使用してみます。


サンプルデータ



こちらのドキュメントを参考にしました。
Aggregation Examples

こんなデータを事前に登録しておきます。


'user':'symfo', 'value':'symfo first data', 'tags' : ['dog', 'cat']
'user':'mongo', 'value':'mongo first data', 'tags' : ['cat']
'user':'mongo', 'value':'mongo second data', 'tags' : ['mouse', 'cat', 'dog']
'user':'riak', 'value':'riak first data', 'tags' : []




登録に使用したプログラムはこんな感じ。


  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', 'value':'symfo first data', 'tags' : ['dog', 'cat']})
  9. col.insert({'user':'mongo', 'value':'mongo first data', 'tags' : ['cat']})
  10. col.insert({'user':'mongo', 'value':'mongo second data', 'tags' : ['mouse', 'cat', 'dog']})
  11. col.insert({'user':'riak', 'value':'riak first data', 'tags' : []})







タグに使用されている名称を集計



タグに使用されている文字と、そのタグが使用されている件数を集計してみます。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. import bson.code
  4. # MongoDBに接続
  5. client = pymongo.MongoClient('192.168.1.110', 27017)
  6. db = client.mongo_test
  7. # test_collectionを取得
  8. col = db.test_collection
  9. # タグを分割するJavaScript
  10. mapper = bson.code.Code("""
  11. function () {
  12.     this.tags.forEach(function(z) {
  13.         emit(z, 1);
  14.     });
  15. }
  16. """)
  17. # タグを集計するJavaScript
  18. reducer = bson.code.Code("""
  19. function (key, values) {
  20.     var total = 0;
  21.     for (var i = 0; i < values.length; i++) {
  22.         total += values[i];
  23.     }
  24.     return total;
  25. }
  26. """)
  27. result = col.map_reduce(mapper, reducer, "myresults")
  28. for doc in result.find():
  29.     print(doc)




myresultsというコレクションが作成され、そこに集計結果が登録されます。
実行すると、各タグの名称と使用回数が表示されました。


$ python sample.py
{u'_id': u'cat', u'value': 3.0}
{u'_id': u'dog', u'value': 2.0}
{u'_id': u'mouse', u'value': 1.0}






集計する条件を指定



userがmongoのタグの使用状況を集計してみます。
map_reduceを実行するとき、queryを指定すればOK。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. import bson.code
  4. # MongoDBに接続
  5. client = pymongo.MongoClient('192.168.1.110', 27017)
  6. db = client.mongo_test
  7. # test_collectionを取得
  8. col = db.test_collection
  9. # タグを分割するJavaScript
  10. mapper = bson.code.Code("""
  11. function () {
  12.     this.tags.forEach(function(z) {
  13.         emit(z, 1);
  14.     });
  15. }
  16. """)
  17. # タグを集計するJavaScript
  18. reducer = bson.code.Code("""
  19. function (key, values) {
  20.     var total = 0;
  21.     for (var i = 0; i < values.length; i++) {
  22.         total += values[i];
  23.     }
  24.     return total;
  25. }
  26. """)
  27. # user:mongoのデータのみ集計
  28. result = col.map_reduce(mapper, reducer, "myresults", query={"user": 'mongo'})
  29. for doc in result.find():
  30.     print(doc)





user:mongoのデータのみ集計できました。


$ python sample.py
{u'_id': u'cat', u'value': 2.0}
{u'_id': u'dog', u'value': 1.0}
{u'_id': u'mouse', u'value': 1.0}







Group



user毎に、各々何件ドキュメントが存在するかgroupを使用して数えてみます。


  1. # -*- coding:utf-8 -*-
  2. import pymongo
  3. import bson.code
  4. # MongoDBに接続
  5. client = pymongo.MongoClient('192.168.1.110', 27017)
  6. db = client.mongo_test
  7. # test_collectionを取得
  8. col = db.test_collection
  9. # ユーザーごとの投稿数集計
  10. reducer = bson.code.Code("""
  11. function(obj, prev){
  12.     prev.count++;
  13. }
  14. """)
  15. results = col.group(key={"user":1}, condition={}, initial={"count": 0}, reduce=reducer)
  16. for doc in results:
  17.     print(doc)




SQLでいうgroup byですね。


$ python sample.py
{u'count': 1.0, u'user': u'symfo'}
{u'count': 2.0, u'user': u'mongo'}
{u'count': 1.0, u'user': u'riak'}

関連記事

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

  1. 2014/07/27(日) 17:49:42|
  2. MongoDB
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<MongoDB PyMongo 2.7.1 findでandやor、$gt,$ltを使用する | ホーム | MongoDB PyMongo 2.7.1で「_id」を自分で指定して、登録や検索を行う>>

コメント

コメントの投稿


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

トラックバック

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