hsetを介して設定されているキーの値がnullの場合、文字列「null」としてシリアル化されます。 ハッシュがhgetallを介して取得される場合、返されるオブジェクトの対応する値は、nullではなく文字列「null」です。
node-redisは、redisから取得した文字列値のデータ型変換を行わないことに気付きました。 ブール値、数値などがそれぞれのjavascriptタイプに自動変換されると暗黙のうちに想定していました。 これがプロジェクトの範囲内であると思わない場合は、問題を閉じてください。
それでも、自動変換は便利です。 false値が「false」として取得され、javascriptの真理チェック条件を通過するために発生するバグのデバッグにかなりの時間を費やしました。
そうです、真/偽のものは私をも惹きつけるものです。
確かにパフォーマンスの懸念はありますが、私は実際にライブラリでこれに対処したいと思います。
@brycebaril入力をJSON.stringify / parseにフラグを導入できます。 それは良い解決策になるはずです、そう思いませんか?
たぶん、createClientコンストラクターにオプションがあるかもしれません。 何かのようなもの...
_parse_bool _:「true」をtrueに、「false」をfalseに変換します
_parse_null _:「null」をnullに変換します
では、「true」と「null」の実際の文字列値をどのように処理しますか? 元の入力タイプが何であったかを検出する方法はありません。
@dirkbonhommeが指摘した@Azmisovは、これは良い解決策ではないでしょう。 そのため、JSON.stringify / parseのみを使用することがオプションになる場合があります。
特定のコマンドベースではなく、すべてのコマンドでこれを解決したいと思います。 そうすれば、とにかくすべての引数をチェックするので、パフォーマンスの低下もありません。さらに重要なのは、引数(配列、オブジェクト、引数)をどのように渡しても、どのコマンドでも解決されるからです。
コマンドに未定義またはnull値が含まれている場合は、エラーを返すことをお勧めします。 これはほとんどの場合、渡された引数に問題があることを示しています。
ただし、未定義の値やnull値を異なる方法で処理したい場合があるため、関数を渡すことができるオプションを追加すると、コマンドにnull /未定義の値が含まれている場合にこの関数がトリガーされます。
その関数は常にコマンド名とそれに渡された引数を取得し、戻り値は元の引数を置き換えます。 そうすれば、どのユーザーもこれらの値を必要に応じて処理できます。
同じロジックをtrue / falseに適用できます。
@ NodeRedis / contributors @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);
'address2'がデータでオプションである場合、 null
戻り値は問題ありません。
そうは言っても、それは多くの人にとって壊滅的な変化になると思うので、あなたが提案しているようなものはデフォルトではなくオプションでなければなりません。
@stockholmux同じことについて話すかどうかはわかりません。 戻り値は決して変更されません。
変更したいのは、 null
すると、代わりに文字列'null'
ことです。
client.set('foo', null);
client.get('foo', function (err, res) {
console.log(res); // 'null'
});
私は古い振る舞いを廃止し(一部の人々は問題を回避することで壊れた振る舞いに依存するかもしれません)、今すぐこれを自分で処理してエラーを返すオプションを追加することを計画しているので、私も何も壊しませんそのような値の場合はv.3.0.0。
'null'値の問題は解決されますか?
プログラムで、実際のnull値を表す特別なトークンを定義しますか。 ユーザーが何かをnullに設定すると、そのコマンドをキャプチャしてnull値を特別なトークンに置き換えます。ユーザーがそのことを取得したら、そのコマンドをキャプチャして、特別なトークンを実際のnull値に置き換えますか?
ただの提案。 この問題は本当に厄介です。 どのサイトのどのユーザーも「null」という名前を持つ可能性があるため、ユーザー名を実際のnull値に解析することは望ましくありません。
「入力時のJSON。{parse、stringify}」フラグについて進展または決定がなされましたか? 特定のget / setロジックではなく、これを自動的に実行すると便利です。
ねえ@taylorzane現時点ではほとんど時間がありませんが、それを実装することは間違いなく計画されています。
よかったね。 時間があれば、それを試してみるのもいいでしょうし、使用しているモジュールのソースをハッキングするのも楽しいです。 :+1:
これは今機能していますか?
データをRedisにシリアル化するために別の方法を使用することになったので、これを実装することはできませんでした。
@taylorzaneを共有しても
@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もう1つのオプションは、 ReJSONを使用してJSONオブジェクトを保存することです。通常は、すべてを手動でシリアル化するよりも優れたオプションであり、nullや未定義を処理できます。 これは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に感謝します。外部の依存関係を使用せずに、より良い解決策を思いつきました。アイデアは、2番目の引数であるJSON.stringifyメソッドでreplacer関数を使用することです。
最も参考になるコメント
node-redisは、redisから取得した文字列値のデータ型変換を行わないことに気付きました。 ブール値、数値などがそれぞれのjavascriptタイプに自動変換されると暗黙のうちに想定していました。 これがプロジェクトの範囲内であると思わない場合は、問題を閉じてください。
それでも、自動変換は便利です。 false値が「false」として取得され、javascriptの真理チェック条件を通過するために発生するバグのデバッグにかなりの時間を費やしました。