在redis中存储多个嵌套对象

Geo*_*off 15 json redis

我想在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".....}
       }
Run Code Online (Sandbox Code Playgroud)

我已经检查了 这个提供存储用户的方法的问题,但我想将用户(01,02)存储在用户内,然后将卡车(01,02)存储在卡车中,这样如果我想要检索用户,我可以简单地做

hmget users
Run Code Online (Sandbox Code Playgroud)

和卡车类似的情况

后来我也想在用户中获取user01,但对如何在redis中存储这些数据感到困惑

Not*_*fer 7

您可以使用ReJSON Redis模块直接存储对象.http://rejson.io/


Abh*_*are 5

您可以像附加图像一样以redis格式保存数据.在这张图片中,我为你制作了一个结构

用于用户数据

编辑

示例代码是:

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);



    }
Run Code Online (Sandbox Code Playgroud)

你可以在那些键上做hmget和hmgetAll.


May*_*ain 5

我认为您可以更好地使用HMSET来保存密钥。

就像在您的情况下,您可以创建一个HMSET名称为“用户”和“卡车”的名称。HMSET您可以在其中创建诸如“ user01 ”和“ user02 ”之类的键(即字段)。由于这些键(如“user01”、“user02”等)能够在其中存储值,因此您可以{username:"ally", email:"all@gmail.com"}字符串化形式存储JSON 对象的其余部分(即)。

例如: HMSET users user01 "{\"username\":\"ally\",\"email\":\"all@gmail.com\"}"

在此之后,您可以通过HGETALL获取您的用户列表(例如使用)。同样,如果您需要获取“user01”的用户详细信息,则可以使用HGET like 。获取“user01”的值后,您可以解析该值并根据您的要求使用。HGETALL usersHGET users user01


Red*_*iGu 5

选项1

我认为,如果您正在寻找一种独立于实现语言的方式,即在以不同编程语言编写的系统的不同部分中期望实现相同的操作和结果,那么@Not_a_Golfer的建议最适合您的情况。

选项2

但是,如果您碰巧只使用Java而尚未运行Redis 4.0,我建议您使用Redisson作为客户端库,以使自己的工作更加轻松。

免责声明,我是Redisson项目的成员,以下是我的看法。也希望它能影响到处于这种情况下的其他人。

Redisson是一个客户端Java库,可让您将Redis用作内存数据网格。自然支持多维复杂对象。

Redisson为Redis数据类型提供了标准的Java接口,即hash提供Redis java.util.Mapjava.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);
Run Code Online (Sandbox Code Playgroud)

取出数据同样容易

User user01 = users.get("user01");
Truck truck02 = trucks.get("truck02");
Run Code Online (Sandbox Code Playgroud)

在Redis中,您将获得两个哈希,一个称为users,另一个称为trucks,您将看到JSON字符串是根据这些哈希对象中的指定字段名称存储的。

现在,您可能会争论这不是一个真正的嵌套对象,这只是一个数据序列化。

好的,让示例变得更复杂一点,以了解其中的区别:如果要保留驾驶特定卡车的所有用户的列表,您可能还想轻松地找出用户当前正在驾驶哪辆卡车。

我会说这些是相当典型的业务用例。

这确实增加了数据结构的维度和复杂性。通常,您必须将它们分成不同的部分:

  • 您需要将TruckUser映射到其他哈希,以避免数据重复和一致性问题;

  • 您还需要为每辆卡车管理一个单独的列表,以存储使用情况日志。

在Redisson中,这些类型的任务可以更自然地处理,而无需考虑上述担心。

您将像通常那样简单地在Java中这样做:

  • 用@REntity批注注释您的User类和Truck类,然后选择您自己的标识符生成器或说明符,这可以是字段的值。

  • 将列表字段(usageLog)添加到Truck类。

  • 将“卡车”字段(currentDriving)添加到User类。

这就是您所需要的。因此用法并不比您通常在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);
Run Code Online (Sandbox Code Playgroud)

因此,最终您得到的是每个记录都存储在Redis和一个哈希中,并且每个卡车记录都保留了使用它的用户记录的独立列表,用户记录现在具有他/她当前正在驾驶的卡车的信息。所有这些事情都是使用对象引用完成的,而不是复制域记录。

如您所见,Redisson提供了一种解决方案,可以在所有过程中打勾并消除麻烦。

有关与Redisson如何通过对象哈希映射和对象引用处理Redis中的多维复杂对象的更多信息: