【问题标题】:How do I store this type of nested object in redis?如何在redis中存储这种类型的嵌套对象?
【发布时间】:2017-01-22 13:32:12
【问题描述】:
{
    "chats": {
        "Main": {
            "3": {
                "u": "George",
                "n": "G",
                "f": "1",
                "a": "http://example.com/a.png"
            },
            "4": {
                "u": "Lisa",
                "n": "L",
                "f": "1",
                "a": "http://example.com/b.png"
            }
        }
    }
}

我通常将它存储在 node.js 中的一个对象中

我还需要能够将此数据发送给用户。我需要做的一个例子是将聊天中的所有用户发送给登录的新用户。

那就是:users = obj.chats.Main

但我不知道如何将其存储在 redis 中,更不用说如何抓取数据并将其解析回对象以发送给用户了。

随着更多用户登录,此对象将变得相当大,因此假设有 100,000 个用户同时登录,每个不同的聊天可能有 20 个用户。

我需要一个集合中的集合来完成这项工作,但我认为 redis 不可能

【问题讨论】:

标签: node.js redis


【解决方案1】:

一种简单的方法是让每个聊天成为一个 Redis 用户集,其中每个用户都是一个包含其数据的 JSON 字符串。每个聊天可能都有一个类似"chat:Main" 的键。然后,您将拥有另一个包含所有聊天键的 Set(例如,一个名为 "chats" 的 Set,其成员为 "chat:Main" 等)。

现在,如果用户可以出现在大量聊天中,或者如果您希望能够轻松更改用户的各个字段(例如,将 Lisa 的 f 更改为 2),您可以将每个用户表示为 Redis而是散列。在这种情况下,上面提到的集合将包含用户哈希的密钥,而不是数据本身的 JSON 字符串。这会使架构复杂化,但根据您的数据和访问模式,它可能会减少内存使用或提高效率。

要使用该设计获取聊天室信息,您将获取 "chat:Main" 集合的成员,然后循环遍历它们,对每个成员执行 HGETALL。通过使用流水线,您可以在两个 Redis 往返中执行此操作(一个用于获取聊天组的成员,另一个用于处理所有 HGETALLs)。或者,您可以编写一个 Lua 脚本,然后在一次访问 Redis 服务器的过程中完成所有操作。

【讨论】:

  • 感谢您的建议。我确实需要能够轻松更改各个字段。但与此同时,我需要获取所有登录聊天的用户的数据,并在他们登录时将其传递给新用户。(数据必须编译成一个对象)。您建议的方法是否适用于此?
  • @JDel:我已经编辑了答案来解释如何做到这一点。但是如何使用当前的 Javascript 对象编辑单个字段?您是否遍历每个聊天室,每次都在寻找 Lisa 并更改字段?如果您对此感到满意,您可以使用我在第一段中提到的更简单的设计来做同样的事情。
  • 使用对象编辑字段对我来说实际上很容易,因为一切都是这样设置的。在我的情况下,如果用户决定更改他们的昵称,则该功能具有他们的用户 ID 和他们已经登录的聊天。因此,使用对象就像这样做一样简单:obj.chats[chatName][userid].n = "New Nickname";
  • @JDel:如果您只需要在单个聊天中更新单个用户对象,那么更简单的解决方案将变得更加可行。您只需解码 JSON,设置属性,然后重新编码为 JSON。最终,任何一种方式都会奏效,因此只需选择最适合您的设计的折衷方案。
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 2019-02-01
  • 2011-11-26
  • 2011-11-17
  • 1970-01-01
相关资源
最近更新 更多