node.js 在 redis 中存储对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8694871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
node.js store objects in redis
提问by Pono
Here is the thing - I want to store native JS (node.js) objects (flash sockets references) in redis under a certain key. When I do that with simple client.set()it's stored as a string. When I try to get value I get [object Object]- just a string.
事情就是这样 - 我想在 redis 中的某个键下存储本机 JS (node.js) 对象(闪存套接字引用)。当我用 simple 做这件事时,client.set()它被存储为一个字符串。当我尝试获取价值时,我得到的[object Object]只是一个字符串。
Any chance to get this working? Here's my code:
有机会让这个工作吗?这是我的代码:
addSocket : function(sid, socket) {
client.set(sid, socket);
},
getSocket : function(sid) {
client.get(sid, function(err, reply) {
// cant't get an object here. All I get is useless string
});
},
采纳答案by Sergio Tulentsev
Downvoters: the context here is SET command and ability to store arbitrary objects.
Downvoters:这里的上下文是 SET 命令和存储任意对象的能力。
No, you can't do that. You should accept the fact that Redis stores everything as a string (the protocol is text-based, after all). Redis may perform some optimizations and convert some values to integers, but that's its business, not yours.
不,你不能那样做。您应该接受 Redis 将所有内容存储为字符串的事实(毕竟协议是基于文本的)。Redis 可能会执行一些优化并将一些值转换为整数,但这是它的业务,而不是您的业务。
If you want to store arbitraryobjects in Redis, make sure that you serialize them before saving and de-serialize after retrieving.
如果您想在 Redis 中存储任意对象,请确保在保存之前序列化它们并在检索之后反序列化。
I'm not sure if you can do that with socket objects, though. They simply describe a system resource (an open connection), after all (TCP sockets, for example). If you manage to serialize the description and deserialize it on another machine, that other machine won't have the connection.
不过,我不确定您是否可以使用套接字对象来做到这一点。毕竟,它们只是描述了一个系统资源(一个开放的连接)(例如 TCP 套接字)。如果您设法序列化描述并在另一台机器上反序列化它,那台机器将无法连接。
回答by Shawn Janas
Since the socket is of type Object, you need to convert the object to a string before storing and when retrieving the socket, need to convert it back to an object.
由于套接字的类型为Object,因此您需要在存储之前将对象转换为字符串,并且在检索套接字时需要将其转换回对象。
You can use
您可以使用
JSON.stringify(socket)
to convert to a string and
转换为字符串和
JSON.parse(socketstr)
to convert back to an object.
转换回对象。
Edit:
编辑:
Since the release of version 2.0.0, we are able to store objects as hashes into Redis.
自 version 发布以来2.0.0,我们能够将对象作为哈希存储到 Redis 中。
client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
client.hgetall("hosts", function (err, obj) {
console.dir(obj);
});
https://redis.io/commands/hset
https://redis.io/commands/hset
回答by Jason Loveman
The solution below doesn't solve the whole point of using redis -- to share data across cluster instances. Storing an instance-specific id in redis will be meaningless to another instance that tries to use that id.
下面的解决方案并没有解决使用 redis 的全部问题——跨集群实例共享数据。将特定于实例的 id 存储在 redis 中对于尝试使用该 id 的另一个实例来说毫无意义。
However, there is "hmset" which can be called with an object and it will set each object field as a separate redis field in the same key. And it will be converted back to an object when you call hgetall. Unfortunately, I don't think it handles nested objects or arrays within an object, only simple properties whose values can be stored by "toString()".
但是,可以使用对象调用“hmset”,它将每个对象字段设置为同一键中的单独 redis 字段。当你调用 hgetall 时,它会被转换回一个对象。不幸的是,我不认为它处理对象内的嵌套对象或数组,只处理其值可以由“toString()”存储的简单属性。
So an object like
所以一个像
client.hmset("myhashkey",{a:1, b:2, c:'xxx'})
works great and can be retrieved with
效果很好,可以用
client.hmget("myhashkey", function(obj) {
console.log(obj);
});
Not so much for:
没那么多:
client.hmset("myhashkeynested",{a:1, b:2, c:'xxx', d: { d1: 'x', d2: 'y'}});
回答by Zoombear
I also found this to be an incredibly useful tool, especially if you are channeling JSON from an API to your front-end:
我还发现这是一个非常有用的工具,尤其是当您将 JSON 从 API 引导到前端时:
If you're receiving a huge block of JSON and can't store as a specific hash, stringifying it while storing will allow you to retrieve the whole json instead of just "[object Object]".
如果您收到一大块 JSON 并且无法存储为特定的哈希值,则在存储时对其进行字符串化将允许您检索整个 json 而不仅仅是“[object Object]”。
回答by clyfe
I belive that when you store the object, internally, before storage object.toString()is called and that is the value that is stored.
我相信,当您在内部存储对象时,在object.toString()调用storage 之前,这就是存储的值。
({a: 1}).toString() # "[object Object]"
What you need to do is use JSON.encode and JSON.parse.
您需要做的是使用 JSON.encode 和 JSON.parse。
You cannot store (hidden, binary) references.
Otherwise, you might be able to make a correspondence between integers and sockets, and store integers.
您不能存储(隐藏的、二进制的)引用。
否则,您可能能够在整数和套接字之间建立对应关系,并存储整数。
回答by Nick Sotiros
well if you think about it javascript objects are keys who's values may reference other objects, and in the case of sockets possibly native objects. So if redis is external to the executing javascript how will it be able to store a reference to to that object?
好吧,如果您考虑一下,javascript 对象是键,其值可能会引用其他对象,在套接字的情况下可能会引用本机对象。因此,如果 redis 在执行的 javascript 之外,它将如何存储对该对象的引用?
// a and b exist inside the executing javascript, not in the external O/S
a = {}
b = {}
var obj = {
'one': a,
'two': b
}
// how can redis possibly store references to obj, a or b when this application exits?
redis.set('obj', obj)
// same as..
redis.set('obj', obj.toString()) /*or*/ redis.set('obj', "" + obj)
// same as..
redis.set('obj', "[object Object]")
// the trick is to stringify the object
redis.set('obj', JSON.stringify(obj))
// same as..
redis.set('obj', "{'one':{},'two':{}}")
// here redis does not have to store the actual object references but rather a json string representing the object
// this could also work
redis.set('obj', "{'one':a,'two':b}")
// where you would then do:
obj = eval(redis.get('obj'))
// provided that a and b have already been initialized
回答by Shane
You can save a reference to the JavaScript object, using a technique like this. Basically, it extends Object.prototype (doesn't have to) and you can call radd() to add a custom reference to rhash{}, then retrieve the object with rget(). The "reference" is a string so it will fit right into Redis. This means you won't have to .stringify() and .parse() to put/get a copy in the database. However, the object's data will be destroyed when Node shuts down unless its serialized.
您可以使用这样的技术保存对 JavaScript 对象的引用。基本上,它扩展了 Object.prototype(不是必须的),您可以调用 radd() 来添加对 rhash{} 的自定义引用,然后使用 rget() 检索对象。“引用”是一个字符串,因此它适合 Redis。这意味着您不必使用 .stringify() 和 .parse() 在数据库中放置/获取副本。但是,除非已序列化,否则当 Node 关闭时,对象的数据将被销毁。
var OBJECT = Object.prototype;
OBJECT.rhash = {};
OBJECT.rset = function(id, object) {
OBJECT.rhash[id] = object;
return id;
};
OBJECT.rget = function(id) {
return OBJECT.rhash[id];
};
var dog = {
name: "Skippy",
food: "Bacon",
bark: function() {
alert(this.name + "!");
}
};
var id = OBJECT.rset("a123", dog);
var ref = OBJECT.rget("a123");
ref.bark();

