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?
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 id
s and rank_score
s, 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:
keys user:*
id
is a given id (let's we are looking for id 9000): FT.SEARCH userSearch "@id:9000"
rank_score
desc: FT.SEARCH userSearch "@rank_score:*" SORTBY rank_score DESC
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.