Closed Abhishekrawat1916 closed 4 years ago
Hi @Abhishekrawat1916,
You should serialize person
into a string before setting it to Redis. When getting the string back from Redis, you should deserialize it into person
. Normally, you can use JSON or Protobuf to do the serialization work. Take JSON as an example (you need to install nlohmann::json from here):
#include <nlohmann/json.hpp>
#include <sw/redis++/redis++.h>
using namespace std;
using namespace sw::redis;
struct person {
int age;
string name;
};
int main() {
person p1
p1.age = 18;
p1.name = "Abhishek";
// serialize person into a JSON string
nlohmann::json p;
p["age"] = p1.age;
p["name"] = p1.name;
auto val = p.dump(); // JSON string
auto redis_cluster = RedisCluster("tcp://127.0.0.1:30001");
redis_cluster.set("person", val);
auto reply = redis_cluster.get("person");
if (reply) {
// deserialize JSON string to person
auto val = nlohmann::json::parse(*reply);
person p2;
p2.age = val["age"].get<int>();
p2.name = val["name"].get<string>();
}
return 0;
}
However, if your data structure is as simple as this person
, you can use Redis HASH to store it.
#include <sw/redis++/redis++.h>
#include <string>
using namespace std;
using namespace sw::redis;
int main() {
auto redis_cluster = RedisCluster("tcp://127.0.0.1:30001");
redis_cluster.hmset("person", {std::make_pair("age", "18"), std::make_pair("name", "Abhishek")});
// Get all attributes of this person
std::unordered_map<string, string> attributes;
redis_cluster.hgetall("person", std::inserter(attributes, attributes.begin()));
for (const auto & ele : attributes) {
cout << ele.first << "\t" << ele.second << endl;
}
// Only get a single field:
auto age = redis_cluster.hget("person", "age");
if (age) {
cout << *age << endl;
}
return 0;
}
Also there's a third option that is to use redis-protobuf or RedisJSON module to save these user defined data structure into Redis.
If you still have any problem, feel free to let me know :)
Regards
Hi, using JSON library is not suitable for my project. I was trying to store struct in this way but it is giving garabage value. A similar program in c using hiredis works where %b specifier is used. If anyone could help me out, I am providing my code that i am trying.
#include <sw/redis++/redis++.h>
#include<iostream>
using namespace sw::redis;
using namespace std;
struct person
{
int age;
string name;
};
int main(){
person p1;
p1.age=18;
p1.name="Rawat";
try{
Redis redis_cluster = Redis("tcp://127.0.0.1:6379");
char* ch=(char*)&p1;
person* p=(person*)ch;
cout<<p->name<<endl<<p->age<<endl;
auto reply=redis_cluster.set("surname",StringView(ch,sizeof(p1)));
auto reply1=redis_cluster.get("surname");
if(reply1){
// person* p2=(reply);
person* p2=(person*)&reply1;
cout<<p2->age<<endl;
cout<<p2->name<<endl;
//cout<<1<<endl;
}
}
catch(const Error &e){
cout<<"Error"<<endl;
}
}
Hi @Abhishekrawat1916
You must serialize person
object into a string. If you cannot use JSON or Protobuf, you can serialize it to a string and deserialize the string back to person
with std::stringstream
:
#include <sstream>
person p;
p.age = 18;
p.name = "Rawat";
stringstream output;
output << p.age << p.name;
redis_cluster.set("surname", output.str());
auto reply = redis_cluster.get("surname");
if (reply) {
stringstream input(*reply);
person p1;
input >> p1.age >> p1.name;
cout << p1.age << endl;
cout << p1.name << endl;
}
Regards
Thanks, this would really help.
What is the way to store something in plain binary format in redis-plus-plus and just get back the same binary output ?
Basically I have some complex class for which I am using serialization which gives output in plain binary (not a string, which redis set call expects ) and my de serialization uses that binary stream to build back the object.
What do you mean plain binary format? Do you have a const char *
pointer and a length? If you do, you can manually create a StringView
object, and pass it as parameter to Redis::set
:
const char *data; // pointer to your binary data
size_t len; // length of your data
redis.set("key", StringView(data, len));
It worked thanks :)