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

Comment implémenter cette opération de requête et de mise à jour mongodb (pilote CSharp) ?

Si je comprends l'essentiel, vous voulez essentiellement

  1. Tirez l'élément qui n'est pas requis de votre tableau de références
  2. Définissez la valeur de votre champ de référence principale sur le premier élément du tableau modifié

Et faites tout cela en une seule mise à jour sans déplacer les documents d'un bout à l'autre du réseau.

Mais cela ne peut malheureusement pas être fait. Le principal problème avec ceci est qu'il n'y a aucun moyen de faire référence à la valeur d'un autre champ dans le document en cours de mise à jour. Même ainsi, pour le faire sans itérer, vous devrez également accéder au modifié tableau afin d'obtenir le nouveau premier élément.

Une approche consiste peut-être à repenser votre schéma afin d'accomplir ce que vous voulez. Mon option ici élargirait un peu vos documents de référence et supprimerait le besoin du champ de référence principal.

Il semble que l'hypothèse avec laquelle vous êtes prêt à vivre avec les mises à jour est que si la référence supprimée était la référence principale, vous pouvez simplement définir la nouvelle référence principale sur le premier élément du tableau. Dans cet esprit, considérez la structure suivante :

refs: [ { oid: "object1" }, { oid: "object2" }, { oid: "object5", main: true } ]

En les remplaçant par des documents avec un oid propriété qui serait définie sur l'ObjectId, il donne la possibilité d'avoir une propriété supplémentaire sur le document qui spécifie quelle est la valeur par défaut. Cela peut facilement être interrogé pour déterminer quel identifiant est la référence principale.

Maintenant, considérez également ce qui se passerait si le document correspondant à "object5" dans le champ oid était extrait du tableau :

refs: [ { oid: "object1" }, { oid: "object2" } ]

Ainsi, lorsque vous demandez quelle est la main-reference selon la logique précédente, vous acceptez le premier document du tableau. Maintenant bien sûr, selon les exigences de votre application, si vous souhaitez définir une main-reference différente vous venez de modifier le document

refs: [ { oid: "object1" }, { oid: "object2", main: true } ]

Et maintenant, la logique reste de choisir l'élément de tableau qui a la propriété principale comme true se produirait de préférence, et comme indiqué ci-dessus, si cette propriété n'existe sur aucun élément du document, revenez au premier élément.

Avec tout cela digéré, votre opération pour extraire toutes les références à un objet de ce tableau dans tous les documents devient assez simple, comme cela se fait dans le shell (le même format devrait s'appliquer fondamentalement à n'importe quel pilote):

db.books.update(
   { "refs.oid": "object5" },
   { $pull: { refs: {oid: "object5"} } }, false, true )

Les deux arguments supplémentaires de la requête et de l'opération de mise à jour étant upsert et multi respectivement. Dans ce cas, upsert n'a pas beaucoup de sens car nous ne voulons modifier que des documents qui existent, et multi signifie que nous voulons mettre à jour tout ce qui correspond. La valeur par défaut consiste à modifier uniquement le premier document.

Naturellement, j'ai raccourci toute la notation, mais bien sûr, les valeurs peuvent être des ObjectId réels selon votre intention. Il semblait également raisonnable de supposer que votre utilisation principale de la main-reference est une fois que vous avez récupéré le document. Définir une requête qui renvoie la main-reference en suivant la logique qui a été décrite devrait être possible, mais dans l'état actuel des choses, j'ai beaucoup tapé ici et j'ai besoin de faire une pause pour le dîner :)

Je pense que cela présente un cas valable pour repenser votre schéma afin d'éviter des itérations sur le fil pour ce que vous voulez réaliser.