私の現在のプロジェクトでは、多くのドキュメント(約1,000億)を保存するためにMongoを使用しています。 フィールド_idを使用して最も古いドキュメントの半分を削除するにはどうすればよいですか。インデックス付きフィールド「タイムスタンプ」を使用すると、この操作は現在の速度で約3年後に完了するためです。
2 に答える
タイム スタンプに基づいて ObjectIds を生成する方法について説明している MongoDB ユーザー Google グループの投稿へのリンクを次に示し ます。
投稿から: Mongo ObjectIds からのタイムスタンプの抽出は、Mongo ドキュメントの「オブジェクト ID の最適化」 http://www.mongodb.org/display/DOCS/Optimizing+Object+IDs#OptimizingObjectIDs-Extractinsertiontimesfromidratherthanhavingaseparatetimestampfieldで説明されています。
投稿の例から、ObjectIds は Unix 時間の秒単位で作成される場合があります。
> now = new Date()
ISODate("2012-04-19T19:01:58.841Z")
> ms = now.getTime()
1334862118841
> sec = Math.floor(ms/1000)
1334862118
> hex = sec.toString(16)
4f906126
> id_string = hex + "0000000000000000"
4f9061260000000000000000
> my_id = ObjectId(id_string)
ObjectId("4f9061260000000000000000")
上記の式を使用すると、任意の日付から ObjectID を作成し、より少ない ObjectId を持つドキュメントを照会できます。
今後、アプリケーションが時間に基づいてデータを保存し、一定の期間に達するとデータを削除する場合は、ドキュメントを別のコレクションに保存する方が望ましい場合があります。日ごと、週ごと、またはアプリケーションに最も適した時間枠に 1 つ。コレクション全体の削除は、1 回の操作で実行できるため、個々のドキュメントを削除するよりもはるかに少ないオーバーヘッドで済みます。 db.<collection>.remove({query})
返された各ドキュメントに対して書き込み操作を実行しますが、これは、ご覧のとおり、多数のドキュメントでは非常に遅くなる可能性があります。
単純に中間の_idを見つけて、古いエントリをすべて削除します。
モンゴシェル:
// get total documents count / 2
var c = Math.floor( db.collection.stats()['count'] / 2 )
// find middle id
var mid_id = db.collection.find().skip(c).limit(1)[0]._id
// remove all ids older than the middle one
db.collection.remove({_id:{$lt:mid_id}})