如何在Redis中搜索哈希键?

43

我正在使用哈希键来存储用户的详细信息,例如:

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

我需要搜索年龄为 25,姓名为 lee 的用户。如何在给定字段中搜索指定值?


1
Redis文档中最近新增了一个页面,提供了有关Redis的二级索引的更多信息,并在非范围索引部分涵盖了此案例。 - Itamar Haber
3个回答

71

你不能这样做。Redis是一个键值存储,而不是关系型数据库。

为了搜索特定数据,您需要建立一个访问路径以访问这些数据。例如,要获取年龄为25岁的用户,您需要建立一个映射年龄值到用户的索引。可以使用set完成此操作。名称也是同样如此。

一旦您有了年龄和名称的集合,就可以通过交集来搜索用户。例如:

# 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

我也遇到了同样的设计问题,但我的问题是在执行“sinter age:25 name:lee”命令后,结果应该是ID列表。因此,我需要再次查询以获取真实的用户数据。这是唯一的方法吗? - Ray Shih
5
如果您想执行一次往返操作,一个服务器端的Lua脚本将会实现您想要的功能(即执行SINTER操作,然后对所选项目进行一次HGETALL操作)。 - Didier Spezia
维护哈希本身没有意义,因为您已经为所有哈希字段存储了反向索引。 - droidlabour
那么,在Redis中使用哈希而不是仅将编组对象(如JSON)保存为字符串的唯一优点是可以获取单个字段吗? - Hubro
现在可以了!这个答案仅适用于 Redis 的早期版本。 - FredTheWebGuy

8
实际上,您可以通过将值放入键中来实现。
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

现在您可以使用“keys”命令找到它们。
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"

最终找到特定的哈希值

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

我说的是,你可以分两步完成它。首先,在键中放入所需数量的任意值,然后查找它们。但请注意,将所有值都放在键中并不是一个好主意,只需放入需要进行筛选的值即可。祝好! :)

12
虽然这可能有效,但我真的不建议在构建任何严肃项目时使用它。在 Redis 文档中,特别警告不要在生产环境中使用 KEYS 命令,因为它可能会降低大型数据库的性能:https://redis.io/commands/keys。 - xiy

0

SCAN 是在 Redis v6.0 及以上版本 中推荐的搜索键的方式。

 127.0.0.1:6379>  SCAN 0 TYPE hash COUNT 1000000

需要将COUNT作为最后一个参数传递,否则默认只返回10条记录的限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接