MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongodb met à jour un nombre limité de documents

Par Sammaye, il ne semble pas qu'il y ait une "bonne" façon de faire cela. Ma solution de contournement était de créer un séquence comme indiqué sur le site mongo et ajoutez simplement un champ 'seq' à chaque enregistrement de ma collection. J'ai maintenant un champ unique qui peut être trié de manière fiable pour être mis à jour.

Le tri fiable est important ici. J'allais juste trier sur le _id généré automatiquement mais j'ai rapidement réalisé que l'ordre naturel n'est PAS le même que l'ordre croissant pour les ObjectId (de cette page il semble que la valeur de la chaîne ait priorité sur la valeur de l'objet qui correspond au comportement que j'ai observé lors des tests). De plus, il est tout à fait possible qu'un enregistrement soit déplacé sur le disque, ce qui rend l'ordre naturel peu fiable pour le tri.

Alors maintenant, je peux interroger l'enregistrement avec le plus petit "seq" qui n'a PAS déjà été mis à jour pour obtenir un point de départ inclusif. Ensuite, j'interroge les enregistrements avec 'seq' supérieur à mon point de départ et saute (il est important de sauter car le 'seq' peut être clairsemé si vous supprimez des documents, etc...) le nombre d'enregistrements que je veux mettre à jour. Mettez une limite de 1 sur cette requête et vous avez un point de terminaison non inclusif. Maintenant, je peux émettre une mise à jour avec une requête 'mis à jour' =0, 'seq'>=mon point de départ et

Voici à nouveau les étapes :

  1. créer une séquence d'auto-incrémentation à l'aide de findAndModify
  2. ajoutez un champ à votre collection qui utilise la séquence d'auto-incrémentation
  3. requête pour trouver un point de départ approprié :db.xx.find({ updated :0 }).sort({ seq :1 }).limit(1)
  4. requête pour trouver un point de terminaison approprié :db.xx.find({ seq :{ $gt:startSeq }}).sort({ seq :1 }).skip(updateCount).limit(1)
  5. mettre à jour la collection en utilisant les points de début et de fin :db.xx.update({ updated :0, seq :{ $gte :startSeq }, seq :{ $lt:endSeq }, $isolated :1}, { updated :1 },{ multi :vrai })

Assez douloureux mais ça fait le travail.