Mongo Javaドライバーmongo-java-driver-2.8.0.jarを使用して、期待される構造に一致しないレコードを更新する単一のコレクション内のすべてのレコードにアクセスするGroovyスクリプトがあります。スクリプトはチャンピオンのように機能しますが、コレクションが実際に持っているよりも多くのレコードを処理する理由について頭を悩ませています。または、より正確には、dbCursore.hasNext()は、コレクションが実際に持っているよりも多くのレコードを繰り返し処理します。これは、スクリプトが更新するものを見つけた場合にのみ発生します。スクリプトが更新なしで実行される場合、処理される総数は正しいです。
hasNext()は「最初からやり直す」のですか、それともレコードが更新されている場合、レコードはイテレーション内で移動しますか?
これがコードです...
static def doIt( mongo, normalizer, isDryRun ) {
def ttlProcessed = 0
def ttlCandidates = 0
def ttlUpdated = 0
def lapCount = 0;
def lapStartTime = System.currentTimeMillis();
def db = mongo.getDB( "devices" )
DBCollection dbCollection = db.getCollection( "profiles" )
DBCursor dbCursor = dbCollection.find();
while ( dbCursor.hasNext() ) {
DBObject source = dbCursor.next();
DBObject normalized = normalizer.normalize( source )
// Only update if changed...
if ( ! ( source.equals( normalized ) ) ) {
ttlCandidates++
if ( !isDryRun ) {
BasicDBObject searchQuery = new BasicDBObject( "_id", normalized.get( "_id" ) )
WriteResult result = dbCollection.update( searchQuery, normalized, false, false, WriteConcern.SAFE );
ttlUpdated++
}
}
ttlProcessed++;
if ( ttlProcessed % 10000 == 0 ) {
printErr "split: ${lapCount}, splitElapsed: ${calcElapsed( lapStartTime) } ms, elapsed: ${calcElapsed( startTime )} ms, processed: ${ttlProcessed}, candidates: ${ttlCandidates}, updated: ${ttlUpdated}"
lapCount++
lapStartTime = System.currentTimeMillis()
}
}
printErr "split: ${lapCount}, splitElapsed: ${calcElapsed( lapStartTime) } ms, elapsed: ${calcElapsed( startTime )} ms, processed: ${ttlProcessed}, candidates: ${ttlCandidates}, updated: ${ttlUpdated}"
}
実行によってレコードが更新された場合、ttlProcessedが処理中のコレクションのカウントよりも高い値を取得するのはどうしてですか?