How to search in redis for hash keys?
Asked Answered
M

3

44

I'm using hash keys to store user details like:

 hmset user:1 user_name lee  age 21
 hmset user:2 user_name david  age 25
 hmset user:3 user_name chris  age 25

I need to search for users having age = 25, name = lee. How to do a search for a specified value in a given field?

Mejia answered 13/7, 2012 at 12:24 Comment(1)
A recently added page in Redis' documentation provides more information about Secondary indexing with Redis and covers this case under the Non range indexes section.Saddlery
S
72

You cannot. Redis is a key-value store, not a relational database.

In order to search for a specific data, you need to build an access path to this data. For instance, to get the users having age = 25, you need to build an index to map the age values to users. It can be done with a set. This is the same for the name.

Once you have sets for age and name, you can search users by intersecting the sets. For example:

# Add 3 users
hmset user:1 user_name lee age 21
hmset user:2 user_name david age 25
hmset user:3 user_name chris age 25

# Maintain age index
sadd age:21 1
sadd age:25 2 3

# Maintain name index
sadd name:lee 1
sadd name:david 2
sadd name:chris 3

# Get the ID of users having age = 25 and name = lee
sinter age:25 name:lee
  -> will return an empty set
Sissie answered 13/7, 2012 at 13:14 Comment(5)
I'm facing same design problem, but my question is after the command "sinter age:25 name:lee", the result should be list of id. So I need to query second time to get the real user data. Is this the only way to do?Vibrio
If you want to perform a single roundtrip, a server-side Lua script will do what you want (i.e. sinter, and then one hgetall per selected item).Sissie
It doesn't makes sense to maintain the HASH itself coz you're already storing the reverse index for all the HASH fields.Majolica
So really the only advantage of using hashes in Redis rather than just saving marshalled objects (like JSON) as strings is that you can fetch single fields?Cutshall
Now you can! This answer only applies to early versions of Redis.Tori
B
8

Acually You can do it with put values in key

HMSET lee:25 user_name lee age 25
HMSET massi:43 user_name massi age 43
HMSET lee:24 user_name lee age 24
HMSET lee:28 user_name lee age 28 city Berlin

Now you can find them with "keys" command

127.0.0.1:6379> keys *:25
1) "lee:25"
127.0.0.1:6379> keys lee*
1) "lee:25"
2) "lee:24"
3) "lee:28"
127.0.0.1:6379> keys massi:43
1) "massi:43"

Finally find specific hashes

127.0.0.1:6379> HGETALL lee:24
1) "user_name"
2) "lee"
3) "age"
4) "24"

All that I said is that you can do it in two steps put any number of values that you need in key then find them. But consider that it's not a good idea to put all values inside key Just put ones that you need to do filtering with. Cheers :)

Benco answered 17/1, 2017 at 15:51 Comment(1)
While this may work, I really would recommend against this for building anything serious. In the Redis docs, there's a specific warning against using the KEYS command in a production environment as it can degrade performance in a large database: redis.io/commands/keys.Harbert
T
0

SCAN is the recommended way to search keys in Redis v6.0 and later.

 127.0.0.1:6379>  SCAN 0 TYPE hash COUNT 1000000

COUNT needs to be passed as last parameter, otherwise there will be a limit of 10 records returned by default.

Tori answered 4/3, 2023 at 3:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.