I cross the information of @SWilly22 and by reading the structure of replyRedis
, I discover that it's possible to do RedisGraph queries by using hiredis. Here's how, by an example code using the example Graph Query of the REAMDE's RedisGraph Project.
This is the query to create the example :
GRAPH.QUERY MotoGP "CREATE (:Rider {name:'Valentino Rossi'})-[:rides]->(:Team {name:'Yamaha'}), (:Rider {name:'Dani Pedrosa'})-[:rides]->(:Team {name:'Honda'}), (:Rider {name:'Andrea Dovizioso'})-[:rides]->(:Team {name:'Ducati'})"
Here is the query that we want to execute with hiredis :
GRAPH.QUERY MotoGP "MATCH (r:Rider)-[:rides]->(t:Team {name:'Ducati'}) RETURN count(r)"
So here's an example of how to do it in C by using hiredis :
#include <hiredis/hiredis.h>
#include <stdlib.h>
#include <stdio.h>
#define REDIS_CONTEXT redisContext *context = redisConnect("127.0.0.1", 6379);\
if (context == NULL || context->err) {\
if (context) {\
printf("Error: %s\n", context->errstr);\
return -3;\
} else {\
printf("Can't allocate redis context\n");\
return -4;\
}\
} else printf("connected!\n");
int
main(void) {
REDIS_CONTEXT;
redisReply *reply = redisCommand(context, "GRAPH.QUERY MotoGP %s", "MATCH (r:Rider)-[:rides]->(t:Team {name:'Ducati'}) RETURN count(r)");
/* Note : you can also try this Query the result is on the readme project
* RedisGraph and gives you aproximatively the same response. */
//redisReply *reply = redisCommand(context, "GRAPH.QUERY MotoGP %s", "MATCH (r:Rider)-[:rides]->(t:Team) WHERE t.name = 'Yamaha' RETURN r.name, t.name");
if( reply == NULL )
return 1;
for(int i=0; i<reply->elements; i++) {
printf("\tstr\t:%s#\n",reply->element[i]->str);
printf("\ttype\t:%d#\n",reply->element[i]->type);
printf("\tinteger\t:%llu#\n",reply->element[i]->integer);
printf("\tdval\t:%f#\n",reply->element[i]->dval);
printf("\tlen\t:%zu#\n",reply->element[i]->len);
printf("\tvtype\t:%s#\n",reply->element[i]->vtype);
printf("\telements\t:%zu#\n",reply->element[i]->elements);
for(int j=0; j<reply->element[i]->elements; j++)
switch( reply->element[i]->element[j]->type ) {
case REDIS_REPLY_STRING :
printf("\t\tstr:%s\n",reply->element[i]->element[j]->str);
break;
case REDIS_REPLY_INTEGER :
printf("\t\tinteger:%lld\n",reply->element[i]->element[j]->integer);
break;
case REDIS_REPLY_ARRAY :
printf("\t\t{\n");
for(int k=0; k<reply->element[i]->element[j]->elements; k++)
switch( reply->element[i]->element[j]->element[k]->type ) {
case REDIS_REPLY_STRING :
printf("\t\t\t>str:%s\n",reply->element[i]->element[j]->element[k]->str);
break;
case REDIS_REPLY_INTEGER :
printf("\t\t\t>integer:%lld\n",reply->element[i]->element[j]->element[k]->integer);
break;
default:
continue;
}
printf("\t\t{\n");
break;
default:
continue;
}
printf("---------------------------\n");
}
return 0;
}
Here's the result:
str :(null)#
type :2#
integer :0#
dval :0.000000#
len :0#
vtype :#
elements :1#
str:count(r)
---------------------------
str :(null)#
type :2#
integer :0#
dval :0.000000#
len :0#
vtype :#
elements :1#
{
>integer:1
{
---------------------------
str :(null)#
type :2#
integer :0#
dval :0.000000#
len :0#
vtype :#
elements :2#
str:Cached execution: 1
str:Query internal execution time: 0.856161 milliseconds
---------------------------
Explanation
Here's the struct redisReply :
/* This is the reply object returned by redisCommand() */
typedef struct redisReply {
int type; /* REDIS_REPLY_* */
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
double dval; /* The double when type is REDIS_REPLY_DOUBLE */
size_t len; /* Length of string */
char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
REDIS_REPLY_VERB, REDIS_REPLY_DOUBLE (in additional to dval),
and REDIS_REPLY_BIGNUM. */
char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null
terminated 3 character content type, such as "txt". */
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
} redisReply;
And here's what you obtain with redis-cli :
127.0.0.1:6379> GRAPH.QUERY MotoGP "MATCH (r:Rider)-[:rides]->(t:Team {name:'Ducati'}) RETURN count(r)"
1) 1) "count(r)"
2) 1) 1) (integer) 1
3) 1) "Query internal execution time: 0.624435 milliseconds"
So by analysing the redis-cli reply we can see that we have three elements named 1,2 and 3. Each of them are of type
: REDIS_REPLY_ARRAY
. So now we can enterred in each arrays. In the array called 1 we have one element of type : REDIS_REPLY_STRING
its value is "count(r)"
.
another example
for the query :
GRAPH.QUERY MotoGP "MATCH (r:Rider)-[:rides]->(t:Team) WHERE t.name = 'Yamaha' RETURN r.name, t.name"
by uncommenting the second query in the main function you can have this results :
connected!
str :(null)#
type :2#
integer :0#
dval :0.000000#
len :0#
vtype :#
elements :2#
str:r.name
str:t.name
---------------------------
str :(null)#
type :2#
integer :0#
dval :0.000000#
len :0#
vtype :#
elements :1#
{
>str:Valentino Rossi
>str:Yamaha
{
---------------------------
str :(null)#
type :2#
integer :0#
dval :0.000000#
len :0#
vtype :#
elements :2#
str:Cached execution: 1
str:Query internal execution time: 0.827074 milliseconds
---------------------------
Which correspond to the readme one :
1) 1) "r.name"
2) "t.name"
2) 1) 1) "Valentino Rossi"
2) "Yamaha"
3) 1) "Query internal execution time: 0.625399 milliseconds"
NB : this algorithm is provide under "ASIS" please do not use it in production mode