简单地说,我们现在是Redis

了解更多

短暂搜索的案例

假设你在一个电子商务网站工作,销售家居用品,比如钉子、螺丝、木头、瓷砖、油灰刀之类的东西。这些类型的商店(实体店或网店)通常销售种类繁多的产品。值得注意的是,当一个人从这样的商店购买东西时,很常见的是在以后的时间里需要更多同样的东西——因为谁知道你在一个项目中到底需要多少钉子?

提供快速且易于使用的购买记录对于提供良好的用户体验至关重要,但问题在于细节。一种简单的方法是将项目的时间顺序颠倒过来,但在完成几个项目后,这可能会令人沮丧。客户真正需要的是一种有效搜索单个用户购买历史的方法。

一种方法可能是保存您曾经储存过的所有产品的列表,并为每个项目关联一个表行,然后在关系数据库系统上进行简单的全文搜索。不幸的是,与真正的全文搜索引擎相比,关系数据库的全文搜索功能往往缺乏。

另一种选择是使用一个真正的搜索引擎,它使用一个包含用户名称、产品名称、描述和购买时间的搜索索引——每个索引都是一个文档。如果您将结果限制为特定用户,那么这将为您提供真正的全文搜索功能。不幸的是,这种方法可能很难实现,因为搜索的索引大小会随着每次购买增加越来越多的单个索引而快速增长,而且每次搜索都需要查询任何用户的每一次购买。让我们来计算一下这个索引有多大:

#的客户 每位顾客平均购买的商品数量 #的文档
500,000 150 75000000年

即使用户数量相对有限,这种类型的索引也会迅速失去控制。当你拥有500万用户时会发生什么?一千五百万用户?

这个特性的使用模式非常有趣——在所有用户中,在任何给定的时间,使用情况可能都是相当正常的分布。如果不考虑醒着的时间,你可以假设它不会激增。从侧面考虑,单个用户可能很少接触这个功能。事实上,在大多数情况下,每个用户每周在您的电子商务平台上花费的时间不会超过几分钟。在任何给定的时间,只有一小部分搜索索引被使用。虽然一般的网站搜索应该在任何时候都对所有用户可用,但是购买历史搜索本质上是一个只有登录才能使用的功能。

那么,如果我们可以为每个用户创建一个动态搜索索引会怎么样呢?当用户登录到站点时,购买搜索历史记录将从另一个数据存储填充,然后标记为在特定时间内过期,就像他们的会话一样?如果用户手动注销,您可以安全地删除搜索索引。

这个模式需要一个搜索引擎支持:

  • 轻量级索引创建和删除
  • 指数到期
  • 快速文件索引

如果你拥有所有这些东西,你会得到什么?让我们重新审视我们的简单数学,但让我们添加一个额外的假设:2%的用户基础在任何给定的时间登录。

500000的2% 每位顾客平均购买的商品数量 #的文档
10000活跃用户 150 1,500,000

这种数量的文档比原来的策略更易于管理。此外,它是基于你的网站的实际使用,而不是累积购买历史。所以,如果你的网站变得更加繁忙(通常是事情),然后你可以随着业务的增加而扩大购买历史搜索。

由于购买历史很少更改,因此图中的其他数据存储不需要非常复杂也不需要很高的性能——只在用户登录或购买商品时访问它。它可以像平面文件一样简单。

朝生暮死在RediSearch

既然你是在Redis网站上阅读这篇文章的,你可能会想象你可以在RediSearch中使用这个模式。事实上,reresearch有几个属性和特性与这个用例很好地对齐。首先,由于RediSearch是Redis模块,它继承了Redis本身的大部分性能。和Redis一样,reresearch首先是在内存中,这意味着写和读是在更平等的基础上,不像基于磁盘的系统需要更长的时间来修改或删除数据。快速将购买历史填充到reresearch中不是性能问题。此外,RediSearch还进行了优化,可以快速创建索引以及删除或过期索引。

再深入一点,让我们看看如何在每个用户的基础上创建索引:

> FT.CREATE history:user:1234 TEMPORARY 3600 SCHEMA title TEXT description TEXT purchase

创建这个索引唯一不寻常的地方是临时论点。这告诉RediSearch将搜索索引设置为临时的,并在指定的3600秒(或任何与会话超时一致的时间)之后删除它。任何时候使用搜索索引,添加/删除文档或查询,重置空闲计时器。一旦时间过期,索引将被删除。另外,请注意索引的名称包含一个用户标识符。

在登录时,索引将被填充FT.ADD从其他数据源获取。这里不需要什么特殊的东西—reresearch将文档和键作为临时处理,不需要其他语法。添加文档将是快速的——对于大多数文档来说,在较低的单位数-毫秒范围内。这并不需要同步完成,所以当用户最初浏览网站时,购买历史可以在后台加载。

关于RediSearch有一点需要重申,特别是在这个多索引上下文中:所有文档名在所有索引中都应该是唯一的,以防止在散列级别上的键争用。最后,在某些情况下,可以通过使用NOSAVE选项FT.ADD这将不会存储文档,而只是索引它,仅为您提供文档ID onFT.SEARCH,尽管这使检索结果的过程变得复杂。

实现搜索功能本身很简单。将用户输入作为查询参数FT.SEARCH与reresearchch的任何实现的唯一区别是,索引名称将以某种方式从用户标识符派生出来。

当用户显式注销服务时,FT.DROP命令删除索引和文档。严格地说,这不是必需的操作,因为临时索引将自动过期,但使用显式FT.DROP可以更快地释放资源。

电子商务之外的短暂搜索

这种特定模式并不局限于电子商务应用程序。当您有一组个性化的文档来搜索特定用户时,这是一个可行的模式。想象一下一个财务门户的发票或账单搜索。每个用户只有少数特定于他们的文档,但搜索体验对于查找特定信息至关重要。与此同时,在一个消息应用程序中,你可能想要搜索你的聊天记录,这也是只有在你与应用程序交互时才需要的,而且这个搜索是特定于单个用户的聊天记录的。

这种模式为用户提供了一种优化体验的方法,而无需创建一个庞大而笨重的全局索引,因为维护和扩展起来很有挑战性。这一功能依赖于创建许多有过期时间的轻量级索引和快速动态索引文档的能力。

要开始使用这个模式,请下载在redisearch.io RediSearch或者继续学习reresearch101复述,大学

Baidu