node.js在redis中存储对象

baubqpgj  于 2023-03-28  发布在  Redis
关注(0)|答案(9)|浏览(313)

事情是这样的--我想在redis中存储原生JS(node.js)对象(flash sockets引用),在某个键下。当我使用简单的client.set()时,它被存储为字符串。当我试图获取值时,我得到[object Object]-只是一个字符串。
有机会让它工作吗?这是我的代码:

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
    });
  },
332nm8kg

332nm8kg1#

由于套接字的类型为Object,因此在存储之前需要将对象转换为字符串,并且在检索套接字时需要将其转换回对象。
你可以用

JSON.stringify(socket)

转换为字符串和

JSON.parse(socketstr)

转换回对象。
编辑:
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://github.com/NodeRedis/node_redis

nuypyhwy

nuypyhwy2#

  • Downvoters:这里的上下文是SET命令和存储任意对象的能力。*

不,你不能这么做。你应该接受Redis将所有内容都存储为字符串的事实(毕竟协议是基于文本的)。Redis可能会执行一些优化,并将一些值转换为整数,但这是它的事情,不是你的。
如果要在Redis中存储任意对象,请确保在保存前序列化,检索后反序列化。
不过我不确定套接字对象是否能做到这一点。毕竟,它们只是描述了一个系统资源(一个开放的连接)(例如TCP套接字)。如果您设法在另一台机器上序列化和反序列化该描述,那么另一台机器将不会拥有该连接。

63lcw9qa

63lcw9qa3#

下面的解决方案并没有解决使用redis的全部问题--在集群示例之间共享数据,在redis中存储一个示例特定的id对于另一个试图使用该id的示例来说是没有意义的。
然而,有一个“hmset”可以用一个对象调用,它会将每个对象字段设置为同一个键中的一个单独的redis字段。当你调用hgetall时,它会被转换回一个对象。不幸的是,我不认为它处理嵌套的对象或对象中的数组,只有简单的属性,其值可以通过“toString()"存储。
所以像这样的对象

client.hmset("myhashkey",{a:1, b:2, c:'xxx'})

工作很好,可以检索与

client.hmget("myhashkey", function(obj) {
   console.log(obj);
});

不太适合:

client.hmset("myhashkeynested",{a:1, b:2, c:'xxx', d: { d1: 'x', d2: 'y'}});
vsmadaxz

vsmadaxz4#

我还发现这是一个非常有用的工具,特别是如果你要将JSON从API引导到前端:
node-redis-jsonify
如果你收到一个巨大的JSON块,并且不能存储为特定的哈希,在存储时将其字符串化将允许你检索整个JSON,而不仅仅是“[object Object]”。

8xiog9wr

8xiog9wr5#

我相信,当你在内部存储对象时,在存储object.toString()被调用之前,这就是存储的值。

({a: 1}).toString() # "[object Object]"

你需要做的是使用JSON.encode和JSON.parse。
不能存储(隐藏的、二进制的)引用。
否则,您可以在整数和套接字之间建立对应关系,并存储整数。

oymdgrw7

oymdgrw76#

我们可以使用JSON.stringyfy(obj);之后,我们可以使用JSON.parse(obj)检索原始对象;

const obj = {
   userId: socket.user._id,
   socketId: socket.id,
};
await client.set("user", JSON.stringify(obj));
const usersData = await client.get("user");
pu82cl6c

pu82cl6c7#

你可以在redis中通过在(json.set和json.get)的路径参数中使用'.'来设置JSON值
示例:

await client.json.set(TEST_KEY, '.', { example: 123 });
 const value = await client.json.get(TEST_KEY, {
   path: '.',
});
gk7wooem

gk7wooem8#

如果你想一想,javascript对象是key,它的值可能引用其他对象,在socket的情况下,可能是本机对象。所以如果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
soat7uwm

soat7uwm9#

您可以使用以下技术保存对JavaScript对象的引用(不必)你可以打电话给radd()添加对rhash{}的自定义引用,然后用rget检索对象().“reference”是一个字符串,所以它将适合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();

相关问题