1

I want to update multiple fields on redis with RedisJSON feature, by using Jedis java client;

Refrence

Suppose we have a key:value like below in redis:

PERSON_1:{name=ali2, phone=1234, address=Tehran, education={uniName=Amirkabir}}

then we want to update phone and address fields.

But it seems we can just update only one path or multiple paths with the same field name at a time.

Like:JSON.GET PERSON_1 $phone 9876

If we accept that we can only update one field at a time, than we have to hit the redis twice for two fields.

Is there any way to update multiple fields at a time to keep atomicity and have better performance?

I tried to use Jedis like: client.jsonSet("PERSIN_1", Path.of("phone"), "9876");

and

client.jsonSet("PERSIN_1", Path.of("address"), "Shiraz");

In this way, we hit the Redis sever twice.

3 Answers3

2

There is a JSON.MSET command in the works. Until then you have a few options.

If you just want atomicity, you can use MULTI and EXEC to do it all in a transaction. You'll want to WATCH the key first to make sure that no one else has changed it. Like this:

127.0.0.1:6379> WATCH foo
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> JSON.SET foo $ '{ "alfa": "one" }'
QUEUED
127.0.0.1:6379(TX)> JSON.SET foo $.bravo '"two"'
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
127.0.0.1:6379> JSON.GET foo
"{\"alfa\":\"one\",\"bravo\":\"two\"}"

If someone changes foo before EXEC is called, you'll get an error and then can try again.

You can also do these changes using pipelining to avoid multiple round trips. This just basically shoves all the commands down a socket without waiting for a response.

Jedis supports this but—full disclosure—I've never used pipelining from Jedis before. The docs make it look pretty straightforward though:

Pipeline p = jedis.pipelined();
p.jsonSet("foo", "{ \"alfa\": \"one\" }");
p.jsonSet("foo", "$.bravo", "{ \"alfa\": \"one\" }");
p.sync(); 

If you want to get extra fancy—and who doesn't wanna get extra fancy—you can combine these and use pipelining with transactions.

Hope this helps and good luck!

Guy Royse
  • 2,739
  • 12
  • 9
2

You can use Jedis' Transaction. It will be atomic and have better performance[1].

[1] Performance will be better when there are many commands, compared to a few commands.

sazzad
  • 5,740
  • 6
  • 25
  • 42
1

A JSON.MERGE command is planned to be available soon, which would also allow to do multiple updates on the same key,

And also, as mentioned by Guy Royse, a JSON.MSET command is planned, which would allow to do multiple updates on one or more keys.

oshadmi
  • 136
  • 3