Node-redis: Serialização de valores nulos em um hash

Criado em 13 jun. 2013  ·  19Comentários  ·  Fonte: NodeRedis/node-redis

quando o valor da chave sendo definido por meio de hset é nulo, ele é serializado como string "nulo". Quando o hash é recuperado por meio de hgetall, o valor correspondente no objeto retornado é string "null" em vez de null.

Feature Request v4

Comentários muito úteis

Percebi que o node-redis não faz nenhuma conversão de tipo de dados para valores de string recuperados do redis. Eu havia assumido implicitamente que booleanos, números etc. seriam convertidos automaticamente para o respectivo tipo de javascript. Se você acha que isso não está dentro do escopo do projeto, feche o problema.

Mesmo assim, será bom ter uma conversão automática. Acabei de passar uma quantidade significativa de tempo depurando um bug que surge devido a um valor falso sendo recuperado como "falso" e passando pelas condições de verificação de verdade do javascript.

Todos 19 comentários

Percebi que o node-redis não faz nenhuma conversão de tipo de dados para valores de string recuperados do redis. Eu havia assumido implicitamente que booleanos, números etc. seriam convertidos automaticamente para o respectivo tipo de javascript. Se você acha que isso não está dentro do escopo do projeto, feche o problema.

Mesmo assim, será bom ter uma conversão automática. Acabei de passar uma quantidade significativa de tempo depurando um bug que surge devido a um valor falso sendo recuperado como "falso" e passando pelas condições de verificação de verdade do javascript.

Certo, o verdadeiro / falso é aquele que me pega também.

Na verdade, gostaria de abordar isso na biblioteca, embora haja definitivamente questões de desempenho.

@brycebaril , poderíamos apresentar um sinalizador para JSON.stringify / analisar a entrada. Essa deve ser uma boa solução, você não acha?

Talvez haja uma opção no construtor createClient. Algo como...
_parse_bool_: converte "verdadeiro" em verdadeiro, "falso" em falso
_parse_null_: converte "nulo" em nulo

Mas, então, como você lidaria com o valor real da string de "verdadeiro" e "nulo"? Não há como detectar qual era o tipo de entrada original.

@Azmisov como @dirkbonhomme apontou que esta não seria uma boa solução. Portanto, usar apenas JSON.stringify / parse pode ser uma opção.

Eu gostaria de resolver isso não em uma base de comando específica, mas para todos os comandos. Dessa forma, também não há penalidade de desempenho, já que verificamos cada argumento de qualquer maneira e mais importante: é resolvido para qualquer comando, não importa como você passa os argumentos (array, objeto, argumentos).

Prefiro retornar um erro se algum comando contiver um valor indefinido ou nulo. Isso quase sempre é um sinal de que algo está errado com os argumentos passados.
Algumas pessoas podem querer ter uma maneira diferente de lidar com valores indefinidos e / ou nulos, então eu adicionaria uma opção para a qual você pode passar uma função e esta função é disparada se qualquer comando contiver um valor nulo / indefinido.
Essa função sempre obtém o nome do comando e os argumentos passados ​​a ele e o valor de retorno irá substituir o (s) argumento (s) original (is). Dessa forma, qualquer usuário pode manipular esses valores como quiser.
A mesma lógica pode ser aplicada para verdadeiro / falso.

@ NodeRedis / contributors @dirkbonhomme o que você acha? :)

@BridgeAR Eu discordo que null é 'um sinal de que algo está errado'. Pegue algo assim:

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);

Digamos que se 'address2' for opcional em seus dados, o retorno de null está correto.

Dito isso, acho que seria uma mudança significativa para muitas pessoas, então algo como você está propondo deve ser opcional, não padrão.

@stockholmux Não tenho certeza se falamos sobre o mesmo. O valor de retorno não será alterado de forma alguma.

O que eu quero mudar é que usar null resultará na string 'null' vez disso:

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

Eu também não vou quebrar nada, pois estou planejando descontinuar o comportamento antigo (algumas pessoas podem confiar no comportamento quebrado ao construir em torno do problema) e adicionar a opção de lidar com isso por conta própria agora e retornar um erro de v.3.0.0 para esses valores.

O problema do valor 'nulo' foi resolvido ou não?

Você definiria um token especial em seu programa que representasse o valor nulo real. Quando o usuário define algo como nulo, você captura esse comando e substitui o valor nulo pelo seu token especial. Quando o usuário obtém isso, você captura esse comando e substitui o token especial por um valor nulo real para o usuário?

Apenas uma sugestão. este problema está realmente incomodando. Como qualquer usuário em qualquer site pode ter um nome chamado 'nulo', você não gostaria de analisar o nome de usuário para o valor nulo real;

Algum progresso ou decisão foi feito no sinalizador "JSON. {Parse, stringify} on input"? Seria bom fazer isso automaticamente, em vez de em qualquer lógica get / set.

Ei @taylorzane , tenho pouco tempo no momento, mas está definitivamente planejado para implementar isso.

É bom ouvir isso. Se eu tiver algum tempo, posso tentar, definitivamente seria bom ter, e eu gosto de hackear a fonte dos módulos que uso. : +1:

Isso está funcionando agora?

Acabei usando um método diferente para serializar dados no Redis, então nunca tive a oportunidade de implementar isso.

Se você não se importa em compartilhar @taylorzane, como está armazenando objetos JSON com campos que podem ter valores nulos dentro do Redis

@slidenerd Estou

Exemplo:

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\""
  */
})

Sinta-se à vontade para entrar em contato comigo no Gitter ou pelo e-mail em meu perfil, se desejar mais orientações.

@slidenerd A outra opção é usar ReJSON para armazenar seus objetos JSON - geralmente é uma opção melhor do que serializar tudo manualmente e pode lidar com nulos e indefinidos. É Módulo Redis, então você terá que ter uma versão que o suporte (4.0+) e instalar o módulo no servidor. Está além do escopo deste módulo Node.js (e deste problema), mas resolve o problema.

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

Obrigado @stockholmux, eu vim com uma solução melhor sem usar uma dependência externa, a ideia é usar a função substituta no método JSON.stringify que passa a ser o segundo argumento

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

juriansluiman picture juriansluiman  ·  3Comentários

yuany picture yuany  ·  4Comentários

lemon707 picture lemon707  ·  3Comentários

Stono picture Stono  ·  6Comentários

abhaygarg picture abhaygarg  ·  5Comentários