古いMongoデータベースを継承しました。(読みやすくするため、その内容のほとんどを削除)のは、以下の2つのコレクションに焦点を当ててみましょう:pymongoクエリのパフォーマンスを向上させる方法
コレクションユーザー
db.user.find_one({"email": "[email protected]"})
{'lastUpdate': datetime.datetime(2016, 9, 2, 11, 40, 13, 160000),
'creationTime': datetime.datetime(2016, 6, 23, 7, 19, 10, 6000),
'_id': ObjectId('576b8d6ee4b0a37270b742c7'),
'email': '[email protected]' }
コレクションエントリ(多くのエントリに1人のユーザー):
db.entry.find_one({"userId": _id})
{'date_entered': datetime.datetime(2015, 2, 7, 0, 0),
'creationTime': datetime.datetime(2015, 2, 8, 14, 41, 50, 701000),
'lastUpdate': datetime.datetime(2015, 2, 9, 3, 28, 2, 115000),
'_id': ObjectId('54d775aee4b035e584287a42'),
'userId': '576b8d6ee4b0a37270b742c7',
'data': 'test'}
ご覧のとおり、この2つの間にDBRefはありません。
私がしたいのは、エントリの総数と、指定された日付の後に更新されたエントリの数を数えることです。
これを行うには、私はPythonのpymongoライブラリを使用しました。以下のコードは私に必要なものを手に入れますが、それは痛いほど遅いです。
from pymongo import MongoClient
client = MongoClient('mongodb://foobar/')
db = client.userdata
# First I need to fetch all user ids. Otherwise db cursor will time out after some time.
user_ids = [] # build a list of tuples (email, id)
for user in db.user.find():
user_ids.append((user['email'], str(user['_id'])))
date = datetime(2016, 1, 1)
for user_id in user_ids:
email, _id = user_id
t0 = time.time()
query = {"userId": _id}
no_of_all_entries = db.entry.find(query).count()
query = {"userId": _id, "lastUpdate": {"$gte": date}}
no_of_entries_this_year = db.entry.find(query).count()
t1 = time.time()
print("delay ", round(t1 - t0, 2))
print(email, no_of_all_entries, no_of_entries_this_year)
これは、AWSのサーバー(ないのMongoDBサーバー)上で私のラップトップ上の両方db.entry.find
クエリを実行するために周りに0.83秒かかり、そして0.54。
〜20000人のユーザーがいると、すべてのデータを取得するのに3時間かかります。 Mongoで見られるような待ち時間ですか?これを改善するために私は何ができますか? MongoDBは私にはかなり新しいことを覚えておいてください。
ありがとうございました。しかし、 'CommandCursor'オブジェクトには属性 'values'だけでなくlen(list(entry_counts))== 0もあります.MongoDBのバージョンはおそらく古すぎますか? –
ああ。いいえ、それは単にタイプミスです。ごめんなさい。私はそれを修正します。 – Sevanteri
これで修正されました。そして、うーん、entry_countsが空であるかどうかは分かりません。多分私のテストデータは少し違っていたかもしれません。 – Sevanteri