我想在redis中存储多个复杂的json数据但不确定如何
这是我的json结构
"users":{
"user01":{username:"ally", email:"all@gmail.com"},
"user02":{username:"user2".....}
},
"trucks":{
"truck01":{reg_no:"azn102", make:"subaru" .......},
"truck02":{reg_no:"kcaher3".....}
}
我已经查过了 THis question提供了一种存储用户的方法,但我想将用户(01,02)存储在用户内,然后将卡车(01,02)存储在卡车中,这样如果我想要检索用户,我可以简单地进行3} p>
hmget users
和卡车的类似案例
稍后我还想在用户中获取user01,但对如何在redis中存储此类数据感到困惑
答案 0 :(得分:7)
您可以使用ReJSON Redis模块直接存储对象。 http://rejson.io/
答案 1 :(得分:5)
修改强>
示例代码为:
public void saveInRedis(Jedis jedis) throws JSONException{
JSONObject jsonObject=new JSONObject();
JSONObject jsonObject1=new JSONObject();
JSONObject jsonObject2=new JSONObject();
JSONObject jsonObject3=new JSONObject();
jsonObject2.put("username", "ally");
jsonObject2.put("email", "ally@abc.com");
jsonObject3.put("username", "xyz");
jsonObject3.put("email", "xyz@abc.com");
jsonObject1.put("user01", jsonObject2);
jsonObject1.put("user02", jsonObject3);
jsonObject.put("users", jsonObject1);
// json is -- > {"users":{"user02":{"email":"xyz@abc.com","username":"xyz"},"user01":{"email":"ally@abc.com","username":"ally"}}}
System.out.println("json is --- > "+jsonObject);
JSONObject parse=new JSONObject(jsonObject.toString());
JSONObject parseJson=parse.getJSONObject("users");
JSONObject parseJson2=parseJson.getJSONObject("user02");
JSONObject parseJson3=parseJson.getJSONObject("user01");
Map<String, String> map=new HashMap<>();
Map<String, String> map1=new HashMap<>();
map.put("email", parseJson2.getString("email"));
map.put("username", parseJson2.getString("username"));
map1.put("email", parseJson3.getString("email"));
map1.put("username", parseJson3.getString("username"));
jedis.hmset("users:user01", map);
jedis.hmset("users:user02", map1);
}
你可以在那些键上做hmget和hmgetAll。
答案 2 :(得分:5)
选项1
我认为如果您正在寻找一种独立于实现语言的方式,即在用不同编程语言编写的系统的不同部分中期望相同的操作和结果,那么@Not_a_Golfer 's recommendation最适合您的情况。 / p>
选项2
但是,如果您刚刚使用Java并且尚未运行Redis 4.0,我建议您使用Redisson作为客户端库,以使您自己更轻松地完成这项工作。
免责声明,我是Redisson项目的成员,我的观点存在偏见。它的写作也是希望它可以覆盖到处于这种情况的其他人。
Redisson是一个客户端Java库,可让您将Redis作为内存数据网格运行。自然支持多维复杂对象。
Redisson为Redis数据类型提供标准Java接口,即Redis hash
以java.util.Map
和java.util.concurrent.ConcurrentMap
提供,因此在您的情况下,用法只是:
//lets imagine you have a builder that creates users
User user01 = new User();
user01.setUsername("ally");
user01.setEmail("all@gmail.com");
User user02 = new User();
user02.setUsername("user2");
user02.setEmail("...");
//You get a Redis hash handler that works as a standard Java map
Map<String, User> users = redisson.getMap("users");
//This is how you put your data in Redis
//Redisson serialize the data into JSON format by default
users.put("user01", user01);
users.put("user02", user02);
//the same works for trucks
Truck truck01 = new Truck();
truck01.setRegNo("azn102");
truck01.setMake("subaru");
Truck truck02 = new Truck();
truck02.setRegNo("kcaher3");
truck02.setMake("...");
//The same as above
Map<String, Truck> trucks = redisson.getMap("trucks");
trucks.put("truck01", truck01);
trucks.put("truck02", truck02);
获取数据非常简单
User user01 = users.get("user01");
Truck truck02 = trucks.get("truck02");
在Redis中,您将获得两个哈希值,一个名为users
,另一个名为trucks
,您会看到JSON字符串是根据这些哈希对象中的指定字段名称存储的。
现在,你可能会认为这不是一个真正的嵌套对象,这只是一个数据序列化。
好的,让我们让这个例子看起来更复杂一点:如果你想保留一个驱动某辆卡车的所有用户的清单怎么办,你可能还想轻松找出一个用户是哪辆卡车目前开车。
我想说这些是相当典型的商业用例。
这确实为数据结构增加了更多维度和复杂性。通常你必须将它们分成不同的部分:
您需要将Truck
和User
映射到不同的哈希值,以避免数据重复和一致性问题;
您还需要为每辆卡车管理一个单独的列表来存储使用日志。
在Redisson中,这些类型的任务处理得更自然,并且不会考虑上述担忧。
您可以像往常一样在Java中这样做:
使用@REntity注释注释您的User
类和Truck
类,并选择自己的标识符生成器或说明符,这可能是字段的值。
将一个列表字段(usageLog)添加到Truck类。
将卡车字段(CurrentlyDriving)添加到用户类。
这就是你所需要的一切。因此,用量并不比通常用Java做的多:
//prepare the service and register your class.
RLiveObjectService service = redisson.getLiveObjectService();
service.registerClass(User.class);
service.registerClass(Truck.class);
Truck truck01 = new Truck();
truck01.setRegNo("azn102");
truck01.setMake("subaru");
//stores this record as a Redis hash
service.persist(truck01);
User user02 = new User();
user02.setUsername("user2");
user02.setEmail("...");
//stores this record as a Redis hash
service.persist(user02);
//assuming you have invoked setUsageLog elsewhere.
truck01.getUsageLog().add(user02);
user02.setCurrentlyDriving(truck01);
//under normal circumstance keeping a Redis hash registry is not necessary.
//the service object can be used for this type of look up.
//this is only for demonstration.
Map<String, Truck> trucks = redisson.getMap("trucks");
trucks.put("truck01", truck01);
Map<String, User> users = redisson.getMap("users");
users.put("user02", user02);
所以你最终得到的是每条记录都存储在Redis和一个哈希中,每个卡车记录保存一份独立的用户记录列表,用户记录现在有他/她当前卡车的信息驾驶。所有这些都是使用对象引用完成的,而不是复制域记录。
正如您所看到的,Redisson提供了一个解决方案,可以在所有方框中打勾并在此过程中消除头痛。
有关Redisson如何通过对象哈希映射和对象引用处理Redis中的多维复杂对象的更多信息:
答案 3 :(得分:4)
我认为您可以使用HMSET来保存密钥。
与您的情况一样,您可以创建一个名为&#34; 用户&#34;的HMSET
&安培; &#34;的卡车强>&#34 ;.在HMSET
中,您可以创建关键字(即字段),例如&#34; user01 &#34;和&#34; user02 &#34;。
由于这些键(例如&#34; user01&#34;,&#34; user02&#34;等)能够在其中存储值,因此您可以将其余的(即{username:"ally", email:"all@gmail.com"}
)JSON对象存储在其中stringified表格。
例如:HMSET users user01 "{\"username\":\"ally\",\"email\":\"all@gmail.com\"}"
在此之后,您可以按HGETALL获取用户列表(例如使用HGETALL users
)。
同样,如果您需要获取&#34; user01&#34;的用户详细信息。那么您可以使用HGET users user01
之类的HGET。获取&#34; user01&#34;的值后您可以解析该值并根据您的要求使用。
答案 4 :(得分:1)
Redis是一家重要的超值商店。您无法使用Redis链接两个数据结构。 更好地使用Mongo DB或Couch DB,它们是用于链接数据结构的文档数据库