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

Ascenseur magasin BigDecimal dans MongoDB

Depuis MongoDB v2.6, il n'y a pas de type décimal à chiffres fixes. Les données doivent être enregistrées dans un champ d'un type différent et l'application doit effectuer une traduction à chaque fois.

Potentiellement, les bibliothèques intermédiaires pourraient effectuer cette traduction à la place de votre application. Je suppose que net.liftweb.record ne le fait pas.

Si un double type suffirait pour le(s) champ(s) en question, je recommande de le changer pour plus de simplicité. Mais en supposant que vous utilisez BigDecimal pour de bonnes raisons, il existe des solutions de contournement bien connues. Ce sont :

(1) Stockez-le sous forme de chaîne . Vous pouvez avoir n'importe quelle précision arbitraire. Mais le tri ou la recherche de correspondances de valeurs exactes ne fonctionnera que si vous complétez le côté gauche avec des zéros à une longueur fixe à chaque fois. Même dans ce cas, les nombres positifs et négatifs sont deux plages différentes triées. Les négatifs doivent être triés en sens inverse pour avoir un tri numérique correct. Un exemple de l'ordre MongoDB renverra naturellement ces numéros de chaîne remplis de zéros :

"-0000054321.9876"
"-0000100322"
"0000054321.9876"
"0000100322"

Je crois que le type BigDecimal a un constructeur à partir d'une valeur de chaîne, donc cela pourrait être le plus facile à implémenter dans la fonction de traduction de votre application.

(2) Stockez-le en tant que long décalé (Int64) . Le tri fonctionne, moins d'espace disque est utilisé, pas de problèmes avec négatif vs. positif. Nécessite de décaler les valeurs d'un multiple fixe, ce qui rend un peu illisible lorsque l'on regarde directement la base de données. La précision doit être fixée pour être la même pour toutes les valeurs de toute la collection - OK pour les cas d'utilisation financière ; pas OK pour certains cas d'utilisation scientifique.

(3) Stocker sous forme de paire de nombres , un de part et d'autre de la virgule. Le tri demande un peu de travail supplémentaire. Si vous utilisez des nombres Int32, la précision sera limitée à 9 chiffres de chaque côté de la décimale. Regarder deux colonnes dans la base de données au lieu d'une est bien sûr un peu plus de travail.

Pour un exemple de code Scala, j'ai trouvé que le pilote réactif pour le projet MongoDB a documenté trois solutions de contournement de sérialisation pour BigDecimal . Le premier utilise le double; les deux derniers adoptent encore une autre approche - créer un sous-document entier pour la valeur BigDecimal. Essayer d'interroger des valeurs enveloppées dans des sous-documents serait délicat, je suppose.

Un autre cas réel d'un blog de l'équipe de développement Ebay (Morphia/Java)

PS peut-être que MongoDB ajoutera un type décimal à l'avenir. Il y a une demande de fonctionnalité ouverte pour cela que vous pouvez regarder/upvoter - https://jira. mongodb.org/browse/SERVER-1393