2011-09-12 10 views
1

私は、IDとタイムスタンプを持つ履歴データを含むMongoDBコレクションを持っています。少なくとも1つを保存しているドキュメントを削除する

特定の タイムスタンプより古いコレクションからデータを削除したいとします。しかし、すべてのIDについて少なくとも1つの 文書(最新)がコレクションに残っていなければなりません。いけない

{"id" : "11", "timestamp" : ISODate("2011-09-09T10:27:34.785Z")} //1 
{"id" : "11", "timestamp" : ISODate("2011-09-08T10:27:34.785Z")} //2 

{"id" : "22", "timestamp" : ISODate("2011-09-05T10:27:34.785Z")} //3 
{"id" : "22", "timestamp" : ISODate("2011-09-01T10:27:34.785Z")} //4 

...私は私のコレクションの次のドキュメントがあるとし...と私は 2011-09-07より古いタイムスタンプを持つ文書を削除したいその後、 1および2それらがより新しいので削除される。 4は古いので削除する必要がありますが、は少なくとも1つのドキュメントがコレクションに残る必要があるため、 (これは古いものですが)は削除しないでください。

私はcasbahやmongo コンソールでどのようにこれを行うことができますか?

よろしく、 クリスチャン

答えて

1

私はいくつかの方法を考えることができます。まず、これを試してみてください:

var cutoff = new ISODate("2011-09-07T00:00:00.000Z"); 
db.testdata.find().forEach(function(data) { 
    if (data.timestamp.valueOf() < cutoff.valueOf()) { 
     // A candidate for deletion 
     if (db.testdata.find({"id": data.id, "timestamp": { $gt: data.timestamp }}).count() > 0) { 
      db.testdata.remove({"_id" : data._id}); 
     } 
    } 
}); 

これはあなたが望む仕事です。または、MapReduceジョブを使用して同様に行うこともできます。それを実行するとload("file.js");

db.testdata.mapReduce(map, reduce, {out: "results"});

その後のMapReduce出力削除:db.results.drop();

をシェルに上記のファイルをロードし

var map = function() { 
    emit(this.id, { 
     ref: this._id, 
     timestamp: this.timestamp 
    }); 
}; 


var reduce = function(key, values) { 
    var cutoff = new ISODate("2011-09-07T00:00:00.000Z"); 
    var newest = null; 
    var ref = null; 
    var i; 
    for (i = 0; i < values.length; ++i) { 
     if (values[i].timestamp.valueOf() < cutoff.valueOf()) { 
      // falls into the delete range 
      if (ref == null) { 
       ref = values[i].ref; 
       newest = values[i].timestamp; 
      } else if (values[i].timestamp.valueOf() > newest.valueOf()) { 
       // This one is newer than the one we are currently saving. 
       // delete ref 
       db.testdata.remove({_id : ref}); 
       ref = values[i].ref; 
       newest = values[i].timestamp; 
      } else { 
       // This one is older 
       // delete values[i].ref 
       db.testdata.remove({_id : values[i].ref}); 
      } 
     } else if (ref == null) { 
      ref = values[i].ref; 
      newest = values[i].timestamp; 
     } 
    } 
    return { ref: ref, timestamp: newest }; 
}; 

:テキストファイルにこれをロードします

関連する問題