Node-redis: Sérialisation de valeurs nulles dans un hachage

Créé le 13 juin 2013  ·  19Commentaires  ·  Source: NodeRedis/node-redis

lorsque la valeur de la clé définie via hset est nulle, elle est sérialisée en tant que chaîne "null". Lorsque le hachage est récupéré via hgetall, la valeur correspondante dans l'objet renvoyé est la chaîne "null" plutôt que null.

Feature Request v4

Commentaire le plus utile

J'ai réalisé que node-redis ne fait aucune conversion de type de données pour les valeurs de chaîne récupérées à partir de redis. J'avais implicitement supposé que les booléens, les nombres, etc. seraient automatiquement convertis en type javascript respectif. Si vous estimez que cela n'entre pas dans le cadre du projet, veuillez fermer le sujet.

Mais la conversion automatique sera néanmoins agréable à avoir. Je viens de passer beaucoup de temps à déboguer un bogue survenant en raison d'une fausse valeur récupérée comme "faux" et en passant par les conditions de vérification de la vérité de javascript.

Tous les 19 commentaires

J'ai réalisé que node-redis ne fait aucune conversion de type de données pour les valeurs de chaîne récupérées à partir de redis. J'avais implicitement supposé que les booléens, les nombres, etc. seraient automatiquement convertis en type javascript respectif. Si vous estimez que cela n'entre pas dans le cadre du projet, veuillez fermer le sujet.

Mais la conversion automatique sera néanmoins agréable à avoir. Je viens de passer beaucoup de temps à déboguer un bogue survenant en raison d'une fausse valeur récupérée comme "faux" et en passant par les conditions de vérification de la vérité de javascript.

C'est vrai, le vrai/faux est celui qui me touche aussi.

En fait, j'aimerais aborder cela dans la bibliothèque, bien qu'il y ait certainement des problèmes de performances.

@brycebaril, nous pourrions introduire un indicateur dans JSON.stringify/parse l'entrée. Cela devrait être une bonne solution, vous ne pensez pas ?

Peut-être qu'il peut y avoir une option dans le constructeur createClient. Quelque chose comme...
_parse_bool_ : convertit "vrai" en vrai, "faux" en faux
_parse_null_ : convertit "null" en null

Mais alors, comment traiteriez-vous la valeur de chaîne réelle de « true » et « null » ? Il n'y a aucun moyen de détecter le type d'entrée d'origine.

@Azmisov comme @dirkbonhomme a souligné que ce ne serait pas une bonne solution. Par conséquent, l'utilisation de JSON.stringify/parse uniquement peut être une option.

J'aimerais résoudre ce problème non pas sur une base de commandes spécifique mais pour toutes les commandes. De cette façon, il n'y a pas non plus de pénalité de performance, puisque nous vérifions de toute façon chaque argument et plus important encore : il est résolu pour n'importe quelle commande, quelle que soit la façon dont vous passez les arguments (tableau, objet, arguments).

Je préfère renvoyer une erreur si une commande contient une valeur indéfinie ou nulle. C'est presque toujours un signe que quelque chose ne va pas avec les arguments passés.
Certaines personnes voudront peut-être avoir un moyen de gérer les valeurs non définies et/ou nulles différentes, j'ajouterais donc une option à laquelle vous pouvez passer une fonction et cette fonction est déclenchée si une commande contient une valeur nulle/non définie.
Cette fonction obtient toujours le nom de la commande et les arguments qui lui sont transmis et la valeur de retour va remplacer le ou les arguments d'origine. De cette façon, tout utilisateur peut gérer ces valeurs comme il le souhaite.
La même logique pourrait être appliquée pour vrai/faux.

@NodeRedis/contributors @dirkbonhomme qu'en pensez-vous ? :)

@BridgeAR Je ne suis pas d'accord pour dire que null est "un signe que quelque chose ne va pas". Prend quelque chose comme ça :

var myIndexes = ['one','two','three'], myMulti = client.multi();

myIndexes.forEach(function(aKey) { 
  myMulti.hget(aKey,'username'); 
  myMulti.hget(aKey,'address1');  
  myMulti.hget(aKey,'address2');
});

myMulti.exec(cb);

Dites que si 'address2' est facultatif dans vos données, alors le retour null est correct.

Cela étant dit, je pense que ce serait un changement décisif pour beaucoup de gens, donc quelque chose comme vous proposez devrait être facultatif, pas par défaut.

@stockholmux Je ne suis pas sûr que nous parlions de la même chose. La valeur de retour ne sera en aucun cas modifiée.

Ce que je veux changer, c'est que l'utilisation de null entraînera la chaîne 'null' place :

client.set('foo', null);
client.get('foo', function (err, res) {
    console.log(res); // 'null'
});

Je ne casserai rien non plus, car je prévois de déprécier l'ancien comportement (certaines personnes pourraient s'appuyer sur le comportement cassé en construisant autour du problème) et d'ajouter la possibilité de gérer cela par vous-même dès maintenant et de renvoyer une erreur de v.3.0.0 pour de telles valeurs.

Le problème de la valeur « null » est-il résolu ou non ?

Voudriez-vous définir un jeton spécial dans votre programme qui représente la vraie valeur nulle. Lorsque l'utilisateur définit quelque chose sur null, vous capturez cette commande et remplacez la valeur null par votre jeton spécial. Lorsque l'utilisateur obtient cette chose, vous capturez cette commande et remplacez le jeton spécial par une valeur null réelle pour l'utilisateur ?

Juste une suggestion. ce problème est vraiment dérangeant. Étant donné que n'importe quel utilisateur de n'importe quel site pourrait avoir un nom appelé 'null' , vous ne voudriez pas analyser le nom d'utilisateur à la vraie valeur nulle ;

Des progrès ou une décision ont-ils été pris sur le drapeau "JSON.{parse,stringify} on input" ? Ce serait bien que cela se fasse automatiquement plutôt que dans une logique get/set donnée.

Hey @taylorzane J'ai peu de temps pour le moment mais il est définitivement prévu de le mettre en œuvre.

Ça fait plaisir à entendre. Si j'ai un peu de temps, je peux tenter le coup, ce serait certainement bien d'en avoir, et j'aime bidouiller à la source des modules que j'utilise. :+1:

Est-ce que ça marche maintenant ?

J'ai fini par utiliser une méthode différente pour sérialiser les données dans Redis, donc je n'ai jamais eu le temps de l'implémenter.

Si cela ne vous dérange pas de partager @taylorzane, comment

@slidenerd J'aplatis l'objet JSON, puis je sérialise la valeur de chaque nœud aplati avant de le stocker dans Redis. Donc toutes les valeurs sont des chaînes. C'est très performant même avec des milliers de valeurs dé/sérialisées.

Exemple:

const a = {
  a: {
    b: {
      c: null,
      d: true,
      e: "hello"
    }
  }
}

const b = flatten(a)
console.log(b) /* =>
{
  '/a/b/c': null,
  '/a/b/d': true,
  '/a/b/e': 'hello'
}
*/

Object.entries(b).forEach(([key, value]) => {
  redis.set(key, JSON.stringify(value)) // or
  redis.hset('my_hash', key, JSON.stringify(value)) /*
  => "/a/b/c" -> "null"
  => "/a/b/d" -> "true"
  => "/a/b/e" -> "\"hello\""
  */
})

N'hésitez pas à me contacter sur Gitter ou via l'e-mail dans mon profil, si vous souhaitez plus de conseils.

@slidenerd L'autre option consiste à utiliser ReJSON pour stocker vos objets JSON - c'est généralement une meilleure option que de tout sérialiser manuellement et il peut gérer les

            items.push(JSON.stringify(object, (key, value) => {
                if (value === null || value === undefined) {
                    return undefined
                }
                else {
                    return isNaN(parseFloat(value)) ? value : parseFloat(value)
                }
            }))

Merci @stockholmux, j'ai trouvé une meilleure solution sans utiliser de dépendance externe, l'idée est d'utiliser la fonction de remplacement dans la méthode JSON.stringify qui se trouve être le deuxième argument

Cette page vous a été utile?
0 / 5 - 0 notes