29

I'm using node_redis and I'd like to save a structure like:

{
users : 
    "alex" : { "email" : "[email protected]",
           "password" : "alex123"},
    "sandra" : { "email" : "[email protected]",
           "password" : "sandra123"},
    ...
}

Currently, for each user I create a JSON object:

jsonObj = { "email" : "[email protected]",
            "password" : "alex123"}

and do a

db.hmset("alex", JSON.stringify(jsonObj))

Is it possible to embedded this strucute in another structure (the users one ?) How could I set users["alex"] with this structure ?

2
  • Don't you mean db.hmset("users", "alex", JSON.stringify(jsonObj)) instead of db.hmset("alex", JSON.stringify(jsonObj))??? Commented Sep 24, 2013 at 19:19
  • Check this answer for alternative on how to save nested data structures to Redis. Commented Sep 9, 2019 at 15:23

2 Answers 2

25

As far as I know there isn't native support for nested structures in Redis, but they can be modeled for example with set+hash (similar to hierarchical trees). Hashes are probably best suited for storing fields and values of single JSON object. What I would do is to store each user with a prefix (which is a Redis convention), for example:

db.hmset("user:alex", JSON.stringify(jsonObj));

and then use sets to group users into one set with a key named users. I can then get all of the users keys by smembers command and access each of them individually with hgetall.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks, this is a good approach. Then, when you need to update a particuliar user, do you "srem "users" "user:alex" and create a new set to add to users ?
@Luc: If the update doesn't affect his name which is used as a part of the key "user:alex" then you don't have to remove or add him again to the set. You just change specified fields in that hash and that should be all. In case when you are changing also his name you would probably have to delete the original "user:alex" hash and create new one. Then you would remove "user:alex" from "users" set and add there newly created hash key.
I now use this approach (mix of Hash and Set). But the update does not work by only modifying the user object retrieved. It seems we have to "hmset user:alex user" once again.
I'm not sure that I understand this answer at all. You say that hashes are probably best suited for storing fields and values of a single JSON Object. Why is that better than simply just storing the JSON-encoded value to a string using SET? Are you comparing HSET user:{id} name Fred vs. SET user:{id} '{"name":"Fred"}'? If so, I'd presume that SET (and subsequent JSON parsing) is more often faster than HSET if you are frequently accessing all of the fields of the Object. Thoughts?
SET with JSON parsing being faster is questionable since it would probably highly depend on the string length which will be parsed and subsequently saved whereas HSET will process only required small part of the entire JSON object. If all fields are accessed SET could be a viable option and benchmarks with comparison could be interesting to see.
16

You could store the sub structure as an object and store it's id within the main structure, rather like a pointer. So, given your example, I would do the following

{
users : 
    "alex" : { "email" : "[email protected]",
           "password" : "alex123"},
    "sandra" : { "email" : "[email protected]",
           "password" : "sandra123"},
    ...
}
$x = incr idx:user
hmset user:$x email [email protected] password alex123
sadd list:user $x

$x = incr idx:user
hmset user:$x email [email protected] password sandra123
sadd list:user $x

Hope this possible solution helps

1 Comment

ok great. please consider a vote for the answer if it helped in any way. happy programming.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.