Node-redis: Сериализация нулевых значений в хеше

Созданный на 13 июн. 2013  ·  19Комментарии  ·  Источник: NodeRedis/node-redis

когда значение ключа, устанавливаемого с помощью hset, равно null, оно сериализуется как строка "null". Когда хэш извлекается с помощью hgetall, соответствующее значение в возвращаемом объекте представляет собой строку «null», а не null.

Feature Request v4

Самый полезный комментарий

Я понял, что node-redis не выполняет преобразование типов данных для строковых значений, полученных из redis. Я неявно предполагал, что логические значения, числа и т. Д. Будут автоматически преобразованы в соответствующий тип javascript. Если вы считаете, что это не входит в рамки проекта, закройте проблему.

Но, тем не менее, автоматическое преобразование будет неплохо. Я просто потратил значительное количество времени на отладку ошибки, возникающей из-за того, что ложное значение было получено как «ложное» и прошло через условия проверки истинности javascript.

Все 19 Комментарий

Я понял, что node-redis не выполняет преобразование типов данных для строковых значений, полученных из redis. Я неявно предполагал, что логические значения, числа и т. Д. Будут автоматически преобразованы в соответствующий тип javascript. Если вы считаете, что это не входит в рамки проекта, закройте проблему.

Но, тем не менее, автоматическое преобразование будет неплохо. Я просто потратил значительное количество времени на отладку ошибки, возникающей из-за того, что ложное значение было получено как «ложное» и прошло через условия проверки истинности javascript.

Правильно, истинное / ложное - это то, что меня тоже понимает.

Я действительно хотел бы решить эту проблему в библиотеке, хотя определенно есть проблемы с производительностью.

@brycebaril мы могли бы ввести флаг для JSON. stringify / анализировать ввод. Это должно быть хорошее решение, тебе так не кажется?

Возможно, в конструкторе createClient может быть опция. Что-то вроде...
_parse_bool_: преобразует «истина» в истину, «ложь» в ложь
_parse_null_: преобразует "null" в null

Но как тогда поступить с фактическим строковым значением «истина» и «ноль»? Невозможно определить исходный тип ввода.

@Azmisov, как заметил @dirkbonhomme , это не было бы хорошим решением. Поэтому можно использовать только JSON. Stringify / parse.

Я бы хотел решить эту проблему не для конкретной командной базы, а для всех команд. Таким образом, также не будет потери производительности, поскольку мы все равно проверяем каждый аргумент, и что более важно: он решается для любой команды, независимо от того, как вы передаете аргументы (массив, объект, аргументы).

Я предпочитаю возвращать ошибку, если какая-либо команда содержит неопределенное или нулевое значение. Это почти всегда признак того, что с переданными аргументами что-то не так.
Некоторые люди могут захотеть иметь способ обрабатывать значения undefined и / или null по-разному, поэтому я бы добавил опцию, в которую вы можете передать функцию, и эта функция запускается, если какая-либо команда содержит значение null / undefined.
Эта функция всегда получает имя команды и переданные ей аргументы, а возвращаемое значение заменяет исходный аргумент (ы). Таким образом, любой пользователь может обрабатывать эти значения по своему усмотрению.
Та же самая логика может быть применена для истинного / ложного.

@ NodeRedis / участники @dirkbonhomme что вы думаете? :)

@BridgeAR Я не согласен с тем, что null - это «знак того, что что-то не так». Возьмем что-то вроде этого:

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

Скажем, если «адрес2» в ваших данных является необязательным, тогда возврат null в порядке.

При этом я думаю, что для многих это будет серьезным изменением, поэтому что-то вроде того, что вы предлагаете, должно быть необязательным, а не по умолчанию.

@stockholmux Я не уверен, что мы говорим об одном и том же. Возвращаемое значение ни в коем случае не изменится.

Я хочу изменить то, что использование null 'null' вместо этого приведет к строке

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

Я тоже ничего не сломаю, так как я планирую отказаться от старого поведения (некоторые люди могут полагаться на нарушенное поведение, строясь вокруг проблемы) и добавить возможность справиться с этим самостоятельно прямо сейчас и вернуть ошибку из v.3.0.0 для таких значений.

Решается ли проблема с нулевым значением?

Определите ли вы в своей программе специальный токен, который представляет реальное нулевое значение. Когда пользователь устанавливает значение null, вы захватываете эту команду и заменяете нулевое значение своим специальным токеном. Когда пользователь получает эту вещь, вы фиксируете эту команду и заменяете специальный токен реальным нулевым значением для пользователя?

Просто предложение. этот вопрос действительно беспокоит. Поскольку у любого пользователя на любых сайтах может быть имя, называемое «null», вы не захотите анализировать имя пользователя до реального нулевого значения;

Был ли достигнут какой-либо прогресс или решение по флагу «JSON. {Parse, stringify} on input»? Было бы неплохо, если бы это выполнялось автоматически, а не в какой-либо заданной логике получения / установки.

Привет, @taylorzane, у меня сейчас мало времени, но мы определенно планируем это реализовать.

Приятно слышать. Если у меня есть время, я могу попробовать его, это определенно было бы неплохо, и мне нравится взламывать исходные коды модулей, которые я использую. : +1:

Это сейчас работает?

В итоге я использовал другой метод для сериализации данных в Redis, поэтому мне так и не удалось его реализовать.

Если вы не против поделиться @taylorzane, как вы храните объекты JSON с полями, которые могут иметь нулевые значения внутри с помощью Redis

@slidenerd Я сглаживаю объект JSON, а затем сериализую значение каждого сглаженного узла перед его сохранением в Redis. Итак, все значения - строки. Он достаточно эффективен даже при де / сериализации тысяч значений.

Пример:

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

Не стесняйтесь обращаться ко мне через Gitter или по электронной почте в моем профиле, если вам нужны дополнительные рекомендации.

@slidenerd Другой вариант - использовать ReJSON для хранения ваших объектов JSON - обычно это лучший вариант, когда все сериализуется вручную, и он может обрабатывать значения NULL и undefined. Это модуль Redis, поэтому вам потребуется версия, которая его поддерживает (4.0+), и установить модуль на сервер. Это выходит за рамки этого модуля Node.js (и этой проблемы), но это решает проблему.

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

Спасибо @stockholmux, я придумал лучшее решение без использования внешней зависимости, идея состоит в том, чтобы использовать функцию replacer в методе JSON.stringify, который оказывается вторым аргументом

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

jackycchen picture jackycchen  ·  4Комментарии

yuany picture yuany  ·  4Комментарии

michaelwittig picture michaelwittig  ·  3Комментарии

adamgajzlerowicz picture adamgajzlerowicz  ·  4Комментарии

Stono picture Stono  ·  6Комментарии