我们选择将用户和位置数据存储在 Redis 哈希中。哈希非常适合存储域对象。回想一下,我们选择将每个用户存储在一个哈希中,其键包含用户 ID。例如,以下是 RedisInsight 中的用户 852
如果您使用的是 redis-cli,则可以使用 HGETALL
命令查看用户 852:
127.0.0.1:6379> hgetall ncc:users:852
1) "id"
2) "852"
3) "firstName"
4) "Dominik"
5) "lastName"
6) "Schiffmann"
7) "email"
8) "dominik.schiffmann@example.com"
9) "password"
10) "$2b$05$xbkSwODz1tWqdE7xWb393eiYIQcdiEdbbvhK88.Xr9sW7WxdI26qi"
11) "numCheckins"
12) "9353"
13) "lastCheckin"
14) "1488517098363"
15) "lastSeenAt"
16) "124"
将数据存储在哈希中意味着我们可以轻松高效地检索哈希的内容,前提是我们知道键。因此,查找用户 852 很简单,但我们如何执行以下任何操作?
dominik.schiffmann@example.com
的用户。Redis 是一个键/值数据库。这意味着其数据模型针对按键检索进行了优化。仅凭哈希键无法解决上述查询 - 我们需要其他一些机制来索引数据。
传统上,在键/值数据库中,这意味着添加代码以创建和手动更新索引。例如,要解决查询“哪个用户的电子邮件地址为 dominik.schiffmann@example.com
”,我们可能会创建一个新的字符串键,其中包含该电子邮件地址,其值为用户 ID
127.0.0.1:6379> set ncc:users:byemail:dominik.schiffmann@example.com 852
OK
现在,如果我们只想根据 Dominik 的电子邮件地址获取他的用户详细信息,我们需要遵循两个步骤
127.0.0.1:6379> get ncc:users:byemail:dominik.schiffmann@example.com
"852"
127.0.0.1:6379> hgetall ncc:users:852
1) "id"
2) "852"
3) "firstName"
4) "Dominik"
5) "lastName"
6) "Schiffmann"
7) "email"
8) "dominik.schiffmann@example.com"
9) "password"
10) "$2b$05$xbkSwODz1tWqdE7xWb393eiYIQcdiEdbbvhK88.Xr9sW7WxdI26qi"
11) "numCheckins"
12) "9353"
13) "lastCheckin"
14) "1488517098363"
15) "lastSeenAt"
16) "124"
我们还需要使这些信息保持最新,并与应用程序代码中 ncc:users:852
处哈希的更改保持同步。
可以使用其他 Redis 数据类型创建其他类型的辅助索引。例如,我们可能会 使用 Redis 有序集合作为辅助索引,从而能够执行范围查询,例如“查找签到次数在 1000 到 3000 之间的所有用户”。同样,我们必须在应用程序代码中自行填充和维护此额外的数据结构。
Redis Stack 为我们解决了所有这些问题以及更多问题。它为 Redis 添加了一个索引、查询和全文搜索引擎,可以自动跟踪索引哈希中数据的更改。Redis Stack 提供了一种灵活的查询语言来回答诸如“为我找到加利福尼亚州奥克兰市 10 英里范围内所有评级至少为 3 星且签到次数超过 200 次的健身房”之类的问题,而无需添加代码来在我们的应用程序中构建或维护辅助数据结构。
观看视频,了解如何在我们的示例 Node.js 应用程序中使用 Redis Stack。
在本练习中,您将完成实现一个路由,该路由使用 Redis 返回最后一次签到位于给定位置的所有用户。
使用您的 IDE 打开 node-js-crash-course
文件夹,然后找到文件 src/routes/user_routes.js
。
在此文件中,您将看到一个部分实现的路由 /users/at/:locationId
。要完成此练习,您需要替换此行
const searchResults = await redis.performSearch(
redis.getKeyName('usersidx'),
'TODO... YOUR QUERY HERE',
);
包含正确查询的内容,以返回“lastSeenAt”字段设置为 locationId 值的用户。您需要为此使用“数字范围”语法,因为“lastSeenAt”字段已编入索引为数字。请务必查看 Redis 的 查询语法文档 以获取帮助。
要尝试您的代码,请确保 API 服务器组件正在运行
$ npm run dev
(请记住,这将使用 nodemon 在每次保存代码更改时重新启动服务器)。
然后,将浏览器指向 https://localhost:8081/api/users/at/33
。如果您的查询正确,您应该会看到类似于以下内容的输出(实际用户可能会有所不同,只需确保每个用户的 lastSeenAt
值与您提供的位置 ID 匹配 - 在本例中为 33)
[
{
"id": "238",
"firstName": "Jonas",
"lastName": "Nielsen",
"numCheckins": "7149",
"lastCheckin": "1515248028256",
"lastSeenAt": "33"
},
{
"id": "324",
"firstName": "Frans",
"lastName": "Potze",
"numCheckins": "8623",
"lastCheckin": "1515976232073",
"lastSeenAt": "33"
},
...
]
要帮助您开发查询,请使用 RedisInsight 工作台中的一种指南,或阅读有关 FT.SEARCH 命令 的更多信息。
使用 Express + Redis Stack 寻找大脚怪 RESTful
其他资源
Redis 中的查询、索引和全文搜索