Nested hash in redis
you can't use nested hash in redis,
but in the kind of situation you are asking you can use two hashes, one for key to subkey
and the other one for subkey to your values.
Is it possible to store nested dict in Redis as hash structure?
Redis alone doesn't store nested structures in hashes. There is a good answer for how to work around here.
However, there is a module RedisJSON that supports this and the python redis client includes support for this module.
Load the module in the redis server:
redis-server --loadmodule ../RedisJSON/target/release/librejson.dylib
In python you can then set and retrieve nested dicts or portions of the path.
import redis
from redis.commands.json.path import Path
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
foo = {
"host_data": {
"hostname": "some_host",
"mac_address": "82:fa:8e:63:40:05",
"root_password": {
"is_crypted": True,
"password": "sha512_password"
},
"network": {
"ip_address": "192.168.0.10/24",
"default_gateway": "192.168.0.1",
"vmnic": "vmnic3",
"vlan": 20
},
"dns_servers": [
"dns01.local",
"dns02.local"
]
},
"installation_type": "esxi",
"image_data": {
"type": "vCenter_contentlib",
"host": "vcenter01",
"credential": {
"username": "some_user",
"password": "some_password"
},
"content_library": "the_content_lib_name",
"image_name": "some_image"
},
"host_short_name": "esxi021"
}
redis_connection.json().set("test", Path.rootPath(), foo)
print(redis_connection.json().get("test", '.host_data.hostname'))
Redis – Nested hashes vs. string values
You should consider storing the Access Control List (a list of permissions attached to a user-machine) as a redis hash.
This way you can query the entire collection of permissions for a subject or just query for a particular object permission.
For example, you have the following users (Subjects):
- john:machine1
- john:machine2
- mary:machine1
The following features (or Objects):
- editname
- deletemachine
And the following Permissions:
- Y (access granted)
- N (access denied)
You can have one hash for each subject with key -> field -> value as follows:
ACL:{username}:{machine} -> {object} -> {permission}
So you can query for a particular object permission like this:
redis> HGET ACL:john:machine2 editname
"Y"
Or query the entire the collection of permissions for a subject:
redis> HGETALL ACL:john:machine2
1) "editname"
2) "Y"
3) "deletemachine"
4) "N"
Of course you can choose to store only the granted permissions, and assume a denied permission by default.
Save nested hash in redis via a node.js app
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.
Complex data structures Redis
What would the 'usual' way to store such a data structure (or would
you not?)
For example harry and sally would be stored each in separate hashes where fields would represent their properties like age and weight. Then set structure would hold all the members (harry, sally, ...) which you have stored in redis.
Would you be able to directly get a value (e.g. get harry : age ?)
Yes, see HGET or HMGET or HGETALL.
Once stored could you directly change the value of a sub key (e.g.
sally : weight = 100)
Yes, see HSET.
How can I store nested Hashmap in Redis?
Redis doesn't support it as of now. However there is a way to do it, other than rejson
.
You can convert it into JSON and store in Redis and retrieve. Following utility methods, which I use in Jackson.
To convert Object to String :
public static String stringify(Object object) {
ObjectMapper jackson = new ObjectMapper();
jackson.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
try {
return jackson.writeValueAsString(object);
} catch (Exception ex) {
LOG.log(Level.SEVERE, "Error while creating json: ", ex);
}
return null;
}
Example : stringify(obj);
To convert String to Object :
public static <T> T objectify(String content, TypeReference valueType) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS");
dateFormat.setTimeZone(Calendar.getInstance().getTimeZone());
mapper.setDateFormat(dateFormat);
return mapper.readValue(content, valueType);
} catch (Exception e) {
LOG.log(Level.WARNING, "returning null because of error : {0}", e.getMessage());
return null;
}
}
Example : List<Object> list = objectify("Your Json", new TypeReference<List<Object>>(){})
You can update this method as per your requirement. I am sure, you know, how to add and update in Redis.
Related Topics
Calling Instance Variables Without @
How to Get Multiple-Line User Input in Ruby
Why Is Autoload Failing to Load Files for Gems
Loop Within Loop in Rails Controller
Openssl::Cipher::Ciphererror When Running Staging Db on Local
Why Should You Avoid the Then Keyword in Ruby
New Way of Creating Hashes in Ruby 2.2.0
How to Convert This Ruby String into an Array
Regex to Match Mm/Dd/Yyyy Hh:Mm:Ss Am or Pm
Ruby: Calculate Time Difference Between 2 Times
Ruby File Reading Parallelisim
How to Handle Combination []+= for Auto-Vivifying Hash in Ruby
Ruby Daemon Process to Keep Objects Alive for Transient Ruby Instances
Open-Uri Is Not Redirecing Http to Https
Dangerousattributeerror in Omniauth Railscast Tutorial: Create Is Defined by Activerecord
Active Resource Complaining About Expects an Hash
How to Serialize as Activesupport::Hashwithindifferentaccess Anymore