Je dois créer un nouveau champ sid
sur chaque document dans une collection d'environ 500 000 documents. Chaque sid
est unique et basé sur les champs roundedDate
et stream
existants de cet enregistrement.
Je le fais avec le code suivant:
var cursor = db.getCollection('snapshots').find();
var iterated = 0;
var updated = 0;
while (cursor.hasNext()) {
var doc = cursor.next();
if (doc.stream && doc.roundedDate && !doc.sid) {
db.getCollection('snapshots').update({ "_id": doc['_id'] }, {
$set: {
sid: doc.stream.valueOf() + '-' + doc.roundedDate,
}
});
updated++;
}
iterated++;
};
print('total ' + cursor.count() + ' iterated through ' + iterated + ' updated ' + updated);
Cela fonctionne bien au début, mais après quelques heures et environ 100K enregistre les erreurs avec:
Error: getMore command failed: {
"ok" : 0,
"errmsg": "Cursor not found, cursor id: ###",
"code": 43,
}: ...
C'est un bogue dans la gestion de la session du serveur mongodb. Correction en cours, devrait être corrigé dans 4.0+
(reproduit dans MongoDB 3.6.5)
l'ajout de collection.find().batchSize(20)
m'a aidé avec une performance réduite.
J'ai également rencontré ce problème, mais pour moi, il était causé par un bogue dans le pilote MongDB.
Cela s'est passé dans la version 3.0.x
du paquet npm mongodb
, qui est par exemple. utilisé dans Meteor 1.7.0.x
, où j’ai également enregistré ce problème. Il est décrit plus en détail dans ce commentaire et le fil de discussion contient un exemple de projet confirmant le bogue: https://github.com/meteor/meteor/issues/9944#issuecomment-420542042
La mise à jour du paquet npm vers 3.1.x
a corrigé le problème, car j'avais déjà pris en compte les bons conseils donnés ici par @Danziger.
Lors de l'utilisation du pilote Java v3, noCursorTimeout doit être défini dans FindOptions.
DBCollectionFindOptions options =
new DBCollectionFindOptions()
.maxTime(90, TimeUnit.MINUTES)
.noCursorTimeout(true)
.batchSize(batchSize)
.projection(projectionQuery);
cursor = collection.find(filterQuery, options);