削除するドキュメントを選択するクエリがあります。現在、次のように(Pythonを使用して)手動で削除しています。
for id in mycoll.find(query, fields={}):
mycoll.remove(id)
これはあまり効率的ではないようです。より良い方法はありますか?
編集
OK、クエリの詳細について言及するのを忘れたことをお詫びします。それは重要なことだからです。完全な Python コードは次のとおりです。
def reduce_duplicates(mydb, max_group_size):
# 1. Count the group sizes
res = mydb.static.map_reduce(jstrMeasureGroupMap, jstrMeasureGroupReduce, 'filter_scratch', full_response = True)
# 2. For each entry from the filter scratch collection having count > max_group_size
deleteFindArgs = {'fields': {}, 'sort': [('test_date', ASCENDING)]}
for entry in mydb.filter_scratch.find({'value': {'$gt': max_group_size}}):
key = entry['_id']
group_size = int(entry['value'])
# 2b. query the original collection by the entry key, order it by test_date ascending, limit to the group size minus max_group_size.
for id in mydb.static.find(key, limit = group_size - max_group_size, **deleteFindArgs):
mydb.static.remove(id)
return res['counts']['input']
それで、それは何をしますか?重複キーの数を最大でもmax_group_size
キー値ごとに減らし、最新のレコードのみを残します。それはこのように動作します:
(key, count)
データをペアに MR します。- すべてのペアを反復処理します
count > max_group_size
- でデータをクエリ
key
し、タイムスタンプで昇順 (最も古いものから) に並べ替え、結果をcount - max_group_size
最も古いレコードに制限します。 - 見つかったすべてのレコードを削除します。
ご覧のとおり、これにより、重複を最大で N 個の最新レコードに減らすというタスクが達成されます。つまり、最後の 2 つのステップはforeach-found-remove
、これが私の質問の重要な詳細です。
さて、コレクションの削除コマンドについて。クエリは受け付けますが、ソートと制限が含まれています。removeでできますか?さて、私は試しました:
mydb.static.find(key, limit = group_size - max_group_size, sort=[('test_date', ASCENDING)])
この試みは惨めに失敗します。さらに、それは mongo.Observe を台無しにしているようです:
C:\dev\poc\SDR>python FilterOoklaData.py
bad offset:0 accessing file: /data/db/ookla.0 - consider repairing database
言うまでもなく、foreach-found-remove アプローチが機能し、期待どおりの結果が得られます。
さて、私は十分な文脈を提供し、(うまくいけば)失われた名誉を回復したことを願っています.