Alors, pour répondre directement aux questions...
Le stockage sans schéma est certainement une raison impérieuse d'utiliser MongoDB, mais comme vous l'avez souligné, il est également assez facile de stocker JSON dans un SGBDR. La puissance derrière MongoDB réside dans les requêtes riches contre le stockage sans schéma.
Si je peux souligner un petit défaut dans l'illustration concernant la mise à jour d'un champ JSON, il ne s'agit pas simplement d'obtenir la valeur actuelle, de mettre à jour le document, puis de le renvoyer dans la base de données. Le processus doit être entièrement enveloppé dans une transaction. Les transactions ont tendance à être assez simples, jusqu'à ce que vous commenciez à dénormaliser votre base de données. Ensuite, quelque chose d'aussi simple que l'enregistrement d'un vote positif peut verrouiller les tables de votre schéma.
Avec MongoDB, il n'y a pas de transactions. Mais les opérations peuvent presque toujours être structurées de manière à permettre des mises à jour atomiques. Cela implique généralement des changements spectaculaires par rapport aux paradigmes SQL, mais à mon avis, ils sont assez évidents une fois que vous arrêtez d'essayer de forcer des objets dans des tables. À tout le moins, beaucoup d'autres personnes ont rencontré les mêmes problèmes que vous rencontrerez, et la communauté Mongo a tendance à être assez ouverte et à s'exprimer sur les défis qu'elle a surmontés.
Par "écritures sûres", je suppose que vous voulez dire l'option d'activer une "getLastError()" automatique après chaque écriture. Nous avons un wrapper très fin sur une DBCollection qui nous permet un contrôle précis du moment où getLastError() est appelé. Cependant, notre politique n'est pas basée sur l'"importance" des données, mais plutôt sur le fait que le code suivant la requête s'attend à ce que toute modification soit immédiatement visible dans les lectures suivantes.
D'une manière générale, il s'agit toujours d'un mauvais indicateur, et nous avons plutôt migré vers findAndModify() pour le même comportement. À l'occasion où nous appelons toujours explicitement getLastError(), c'est lorsque la base de données est susceptible de rejeter une écriture, comme lorsque nous insérons() avec un _id qui peut être un doublon.
Je crains de ne pas pouvoir dire si notre politique de sauvegarde/restauration est efficace car nous n'avons pas encore eu à restaurer. Nous suivons les recommandations de MongoDB pour la sauvegarde ; @mark-hillick a fait un excellent travail en les résumant. Nous utilisons des jeux de réplicas et nous avons migré des versions de MongoDB ainsi que introduit de nouveaux membres de réplicas. Jusqu'à présent, nous n'avons eu aucun temps d'arrêt, donc je ne suis pas sûr de pouvoir bien parler à ce stade.
Ainsi, d'après mon expérience, MongoDB offre un stockage de données sans schéma avec un ensemble de primitives de requête suffisamment riche pour que les transactions puissent souvent être remplacées par des opérations atomiques. Il a été difficile de désapprendre plus de 10 ans d'expérience SQL, mais chaque problème que j'ai rencontré a été résolu par la communauté ou directement par 10gen. Nous n'avons pas perdu de données ni eu de temps d'arrêt dont je me souvienne.
Pour le dire simplement, MongoDB est de loin le meilleur écosystème de stockage de données que j'ai jamais utilisé en termes d'interrogation, de maintenance, d'évolutivité et de fiabilité. À moins d'avoir une application qui soit si clairement relationnelle que je ne puisse pas en toute conscience utiliser autre chose que SQL, je ferais tout mon possible pour utiliser MongoDB.
Je ne travaille pas pour 10gen, mais je suis très reconnaissant envers les gens qui le font.