Querying json with RedisJSON

1.6k views Asked by At

I have a list of users in json format i want to display as a table to an admin user on the user interface. I want to store all the users i redis and i am thinking this is how i would store

JSON.SET user $ '{"id":"1","user_id":"1","one": "1","two": "2","three": "3","rank_score": 1.44444}' EX 60
JSON.SET user $ '{"id":"2","user_id":"2","one": "2","two": "2","three": "3","rank_score": 2.44444}'
JSON.SET user $ '{"id":"3","user_id":"3","one": "3","two": "3","three": "3","rank_score": 3.44444}'
JSON.SET user $ '{"id":"4","user_id":"4","one": "4","two": "4","three": "4","rank_score": 4.44444}'

and later get all records user

this command JSON.GET user $ only returns the 4th record.

The multi command still gave me one record

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> json.get user
QUEUED
127.0.0.1:6379(TX)> exec
1) "{\"id\":\"4\",\"user_id\":\"4\",\"one\":\"4\",\"two\":\"4\",\"three\":\"4\",\"rank_score\":4.44444}"

I would like to:

> Get all
> Get all records where id is a given id
> Get all records order by rank_score desc
> Remove record where id is 2

How do i group all my users so that i can get all of them at once?

Edit:

I have made the users_list to nest everything in

JSON.SET user $ '{"users_list":[{"id":"1","user_id":"1","one": "1","two": "1","three": "1","rank_score": 1.44444},{"id":"2","user_id":"2","one": "2","two": "2","three": "2","rank_score": 2.44444},{"id":"3","user_id":"3","one": "3","two": "3","three": "3","rank_score": 3.44444},{"id":"4","user_id":"4","one": "4","two": "4","three": "4","rank_score": 4.44444}]}'

Readable

JSON.SET user $ '{
"users_list":[
{
"id":"1",
"user_id":"1",
"one": "1",
"two": "1",
"three": "1",
"rank_score": 1.44444
},
{
"id":"2",
"user_id":"2",
"one": "2",
"two": "2",
"three": "2",
"rank_score": 2.44444
},
{
"id":"3",
"user_id":"3",
"one": "3",
"two": "3",
"three": "3",
"rank_score": 3.44444
},
{
"id":"4",
"user_id":"4",
"one": "4",
"two": "4",
"three": "4",
"rank_score": 4.44444
}
]
}'

Will have more than 128 users result in an error?

1

There are 1 answers

0
goose_lake On BEST ANSWER

RedisJSON is still a key-value store at its core. There is only one value with a given key. When you call a JSON.SET with the same path on an existing key again, any values provided override the ones that were there before. So calling JSON.SET user $ ... is overwriting keys.

Instead of using a user key, it is standard practice to use user as prefix, storing keys named like user:1, user:2, etc. This is preferable for several reasons (more performant than storing a single JSON document array, can define ACL rules for specific key patterns, etc), but most importantly for your question:

You can use RediSearch's full-text search using FT.SEARCH command to get keys that conform to any needed combination of parameters. For example, all users that have a specific id. It also allows sorting. For example, if you store users like

JSON.SET user:1 $ '{"id":"1","user_id":"1","one": "1","two": "2","three": "3","rank_score": 1.44444}' EX 60
JSON.SET user:2 $ '{"id":"2","user_id":"2","one": "2","two": "2","three": "3","rank_score": 2.44444}'

You can create an index using FT.CREATE for whatever parameters need to be searchable, for example to index their ids and rank_scores, the command is FT.CREATE userSearch ON JSON PREFIX 1 user: SCHEMA id NUMERIC rank_score NUMERIC SORTABLE. To explain in detail, this says: create a search index named userSearch, for JSON-type keys, for all keys with a single prefix user:, with the following fields: id is a number, and rank_score is a sortable number.

Here is how you things you mentioned:

  • Get all (I assume you mean get all users): keys user:*
  • Get all records where id is a given id (let's we are looking for id 9000): FT.SEARCH userSearch "@id:9000"
  • Get all records order by rank_score desc: FT.SEARCH userSearch "@rank_score:*" SORTBY rank_score DESC
  • Remove record where id is 2 (I assume you mean all records): first FT.SEARCH userSearch "@id:2", then for each of the results JSON.DEL key.

For more info read the official documentation, it describes the capabilities of the system in detail.