Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON.SET with GET option #1022

Open
jrwagz opened this issue Jun 15, 2023 · 1 comment
Open

JSON.SET with GET option #1022

jrwagz opened this issue Jun 15, 2023 · 1 comment
Labels

Comments

@jrwagz
Copy link

jrwagz commented Jun 15, 2023

I am looking to implement a reservation system application on top of Redis using RedisJSON and RediSearch, and one of the key features is the ability to:

  • perform complex searches for specific object types
  • based on those searches, attempt to mark one of the results as reserved, if reservation is successful, stop, else try another

In order for this to scale horizontally, I want to use something like the SET command with the GET option. So the logic of the reservation would look like this:

return_value = SET reserved 1 GET
if return_value == 1:
  # object was reserved by another parallel instance, reservation failed
else:
  # object was not already reserved, we reserved it
  # do some stuff with the object
  # when done
  SET reserved 0

However, I'd like this boolean field to be a part of the object's RedisJSON object, and from what I can tell, the JSON.SET command doesn't have a GET option to return the value that was present before the set occurred. Is this possible to add, or is there another way to get this similar style with another JSON command?

A similar command is the JSON.TOGGLE however what I really want is JSON.SET_IF_UNSET where the set only passes if the value was unset before the command started.

Thanks!

@LiorKogan
Copy link
Member

LiorKogan commented Nov 2, 2023

You cannot do it in a single command, but you can first retrieve the list of non-reserved items and then reserve them:

JSON.SET items $ '[ {"name": "a", "reserved": 0}, {"name": "b", "reserved": 1} ]'
JSON.GET items '$[?@.reserved==0].name' 
JSON.SET items '$[?@.reserved==0].reserved' 1
JSON.GET items '$[?@.reserved==1].name'

To ensure atomicity:

JSON.SET items $ '[ {"name": "a", "reserved": 0}, {"name": "b", "reserved": 1} ]'
MULTI
JSON.GET items '$[?@.reserved==0].name' 
JSON.SET items '$[?@.reserved==0].reserved' 1
JSON.GET items '$[?@.reserved==1].name'
EXEC

Is this what you're looking for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants