如何基于Redis Search、Node.js 和 Vue.js实现全局搜索?

21-06-17 banq

全局搜索已在 Web 应用程序中无处不在。全局搜索的典型功能是:
  • 做全文搜索和增产效果
  • 提供过滤器以精确包含或排除
  • 允许根据特定属性对结果进行排序

搜索可能会发生在
  • 非结构化数据,如网络内容、电子邮件、评论/评论等。
  • 具有特定数据模型的结构化数据,如“具有标题、描述和其他字段的产品”等。

选择进行全文搜索的技术取决于以下几个因素:
  • 数据量
  • 准确结果与快速响应之间的权衡
  • 现有堆栈与选择新堆栈的余地
  • 多语言支持等

传统上,RDBMS 仅提供广泛的过滤器和排序功能。搜索功能最多仅限于某些通配符搜索。现代 RDBMS 通过提供全文搜索功能弥补了这一差距。
  • PostgreSQL
  • MySQL等

除了数据库,还有很多专用的搜索引擎
  • Elasticsearch (Lucene) — 基于磁盘
  • Redis 搜索——基于内存等

本博客选择了基于 Redis Search、Node.js 和 Vue.js 的端到端解决方案。
 

Redis Search
RedisLabs 共享的训练存储库中提供了运行 Redis Search (docker) 服务器的说明。还包括书籍的示例数据集。
下面提供了启动服务器和加载示例的步骤摘要:

// 启动Redis服务器(Docker)
 docker run -it --rm --name redis-search -p 6379:6379 redislabs/redisearch:2.0.5
// 克隆git repo,然后加载示例数据
gh repo clone redislabs-training/ru203 docker 
exec -i redis-search redis-cli < commands.redis > output.txt
// 启动redis-cli
 docker exec -it redis-search redis-cli
// 创建书籍索引
FT.CREATE books-idx ON HASH PREFIX 1 ru203:book:details: SCHEMA isbn TAG SORTABLE title TEXT WEIGHT 2.0 SORTABLE subtitle TEXT SORTABLE thumbnail TAG NOINDEX description TEXT SORTABLE published_year NUMERIC SORTABLE average_rating NUMERIC SORTABLE authors TEXT SORTABLE categories TAG SEPARATOR ";" author_ids TAG SEPARATOR ";"


下面RediSearch 命令:
  • 搜索关键字“狗或猫”
  • 按“类别”过滤
  • 排序依据“AVERAGE_RATING”降序排列的结果
  • 匹配只有“标题”字段

FT.SEARCH books-idx "dogs|cats @categories:{Juvenile Fiction}" RETURN 1 title SORTBY average_rating DESC LIMIT 0 5


可以使用redis-modules-sdk客户端库在 Node.js 中执行相同的命令:

// https://www.npmjs.com/package/redis-modules-sdk
const Redisearch = require('redis-modules-sdk').Redisearch;

const client = new Redisearch({
  host: 'localhost',
  port: 6379
});

async function queryBooks(keywords, category) {
  // Connect to the Redis database
  await client.connect();

  const ftCategory = category ? `@categories:{${category}}` : '';

  // FT.SEARCH
  const results = await client.search(
    'books-idx',
    `${keywords} ${ftCategory}`,
    {
      return: { num: 1, fields: ['title'] },
      sortBy: { field: 'average_rating', sort: 'DESC' },
      limit: { first: 1, num: 5 }
    }
  );

  // Disconnect from the Redis database
  await client.disconnect();

  // return results
  return results;
}

exports.queryBooks = queryBooks;

queryBooks('dogs|cats', 'Juvenile Fiction').then((resp) => {
  console.log(resp);
});


 
全局搜索 Vue 组件
Vue 组件是使用 Tailwind CSS 创建的。示例应用程序中包含的功能包括:
  • 带有搜索组件的导航栏
  • 输入字段以接受带有去抖动功能的搜索关键字
  • 具有取消功能的 API 请求以避免竞争

此处提供了该应用程序的代码。代码简单明了。