为收集到的种子信息搭建 Web 搜索服务

2026-02-10 66 浏览 0 评论

在前面的文章中,我们已经完成了种子数据的采集与存储。接下来,一个很自然的需求就是: 如何将这些数据通过 Web 服务的方式提供出来,支持搜索、查询和展示

本文将以 Egg.js v3.x 为基础,搭建一个简单但可扩展的 Web 搜索服务,为后续接入全文检索、分页查询、服务端渲染等能力打下基础。


为什么选择 Egg.js

本项目中我选择了 Egg.js v3.x 作为 Web 服务框架。Egg.js 是阿里开源的一套 Node.js 企业级框架,它以 Koa 作为底层内核,在其基础上进一步增强了:

  • 统一的项目结构约定
  • 插件化体系(数据库、模板、鉴权等)
  • 完善的配置与环境隔离能力
  • 成熟的工程化与最佳实践

官方文档地址: 👉 https://v3.eggjs.org/zh-CN/tutorials

当然,如果你更熟悉 NestJS、Express、Fastify,甚至是 Java / Go 框架 ,也完全可以用你熟悉的技术栈,整体思路是通用的。


初始化项目目录

首先,使用 Egg.js 官方脚手架初始化一个最精简的项目:

npm init egg --type=simple

simple 是 Egg.js 提供的 最小化模板 ,非常适合从零搭建接口服务或搜索服务,没有任何多余依赖。

初始化完成后,项目完整目录结构如下:

your-project-name/          # 项目根目录
├── app/                    # 应用核心目录
│   ├── controller/         # 控制器目录(处理请求、返回响应)
│   │   └── home.js         # 默认首页控制器
│   └── router.js           # 路由配置文件(映射 URL 到控制器)
├── config/                 # 配置文件目录
│   ├── config.default.js   # 默认配置文件(所有环境通用)
│   ├── config.local.js     # 本地开发环境配置(覆盖默认配置)
│   ├── config.prod.js      # 生产环境配置(覆盖默认配置)
│   └── plugin.js           # 插件配置文件(默认空)
├── test/                   # 测试用例目录
│   └── app/
│       └── controller/
│           └── home.test.js # 默认首页控制器的测试用例
├── .autod.conf.js          # autod 工具配置(管理依赖)
├── .eslintignore           # ESLint 忽略文件配置
├── .eslintrc               # ESLint 规则配置
├── .gitignore              # Git 忽略文件配置
├── .travis.yml             # Travis CI 持续集成配置(可选)
├── package.json            # npm 包配置(依赖、脚本命令)
└── README.md               # 项目说明文档

核心目录与文件说明

1. app 目录(业务核心)

  • controller/home.js 默认提供了一个 HomeController ,包含 index 方法,用于处理根路径 / 的请求,返回字符串 hi, egg ,可作为服务是否启动成功的验证入口。

  • router.js 定义路由映射规则,默认将 GET / 映射到 home.index

在后续搜索服务中,我们会在这里新增:

  • 搜索控制器
  • 列表页、详情页接口
  • API 与页面渲染入口

2. config 目录(环境与插件配置)

  • config.default.js 通用配置,如端口号(默认 7001)、应用名称、中间件等。

  • config.local.js 本地开发环境配置,通常用于:

  • 关闭 CSRF 校验

  • 打开调试日志

  • 使用本地数据库

  • config.prod.js 生产环境配置,如:

  • 日志压缩

  • 性能优化

  • 安全策略

  • plugin.js 用于启用 Egg.js 插件(数据库、模板引擎等)。


3. test 目录

Egg.js 内置了基于 egg-mocha 的测试体系,默认提供了一个示例测试用例,可直接通过:

npm test

运行单元测试,对后续搜索接口非常有帮助。


4. package.json

包含:

  • 核心依赖: eggegg-scripts
  • 开发依赖: eslintmocha
  • 启动命令: npm run dev

小结

  1. npm init egg --type=simple 生成的是一个 极简、干净的 Egg.js 项目骨架
  2. 核心关注点集中在 app (业务逻辑)和 config (环境配置)
  3. 默认集成了 ESLint 与测试框架,适合长期维护和扩展

安装数据库插件:egg-mysql

既然是搜索服务,就离不开数据查询。这里我选择 MySQL 作为存储方案,并使用官方推荐的 egg-mysql 插件。

官方文档: 👉 https://v3.eggjs.org/zh-CN/tutorials/mysql

数据库的表结构设计、种子数据的获取与保存,已在前面的文章中介绍过,这里不再重复。

安装插件

$ npm i --save egg-mysql

启用插件

// config/plugin.js
exports.mysql = {
  enable: true,
  package: 'egg-mysql'
};

配置数据库连接

config/config.${env}.js 中配置各环境数据库信息:

// config/config.${env}.js
exports.mysql = {
  // 单数据库信息配置
  client: {
    // host
    host: 'mysql.com',
    // 端口号
    port: '3306',
    // 用户名
    user: 'test_user',
    // 密码
    password: 'test_password',
    // 数据库名
    database: 'test'
  },
  // 是否加载到 app 上,默认开启
  app: true,
  // 是否加载到 agent 上,默认关闭
  agent: false
};

使用方式

await app.mysql.query(sql, values);

如果是单实例数据库,可以直接通过 app.mysql 访问,非常方便。

egg-mysql 底层基于 ali-rds ,如果你之前用过这个库,上手几乎没有学习成本。


安装模板引擎:egg-view-ejs

为了快速构建搜索结果页和详情页,我这里采用了 服务端渲染(SSR) 的方式,因此需要一个模板引擎。

我选择的是 EJS ,对应插件为 egg-view-ejs

官方文档: 👉 https://v3.eggjs.org/zh-CN/core/view


安装插件

$ npm i egg-view-ejs --save

插件配置

// {app_root}/config/plugin.js
exports.ejs = {
  enable: true,
  package: 'egg-view-ejs',
};

// {app_root}/config/config.default.js
exports.view = {
  mapping: {
    '.ejs': 'ejs',
  },
};

创建模板文件

// app/view/hello.ejs
hello <%= data %>

渲染模板

// app/controller/render.js
exports.ejs = async ctx => {
  await ctx.render('hello.ejs', {
    data: 'world',
  });
};

模板会被 编译并缓存 。如果你希望关闭缓存,可以设置:

config.ejs.cache = false

在本地开发环境中,缓存默认是关闭的。


模板 include(模板拆分)

相对路径 include (相对于当前模板文件):

// app/view/a.ejs 引入 app/view/b.ejs
<% include('b.ejs') %>

绝对路径 include (相对于 app/view 目录):

// app/view/home.ejs 引入 app/view/partial/menu.ejs
<% include('/partial/menu.ejs') %>

使用 Layout 布局

可以为页面定义统一布局模板:

// app/view/layout.ejs
<% body %>
// app/controller/render.js
exports.ejs = async ctx => {
  const locals = {
    data: 'world',
  };

  const viewOptions = {
    layout: 'layout.ejs'
  };

  await ctx.render('hello.ejs', locals, viewOptions);
};

这种方式非常适合构建 搜索列表页 + 公共头部 / 底部 的页面结构。


启动服务

最后,启动开发服务:

npm run dev

如果终端没有报错,访问:

👉 http://localhost:7001

页面显示 hi, egg! ,说明 Egg.js Web 服务已经成功跑起来了。


总结与下一步

到这里,我们已经完成了:

  • Egg.js 项目初始化
  • 数据库插件集成
  • 模板引擎配置
  • Web 服务正常启动

下一篇文章 将重点介绍:

  • 如何设计搜索接口
  • 如何从数据库中分页查询种子数据
  • 如何将搜索结果渲染成可用的页面
  • 以及后续如何接入更高级的搜索能力(如全文检索)

如果你对 Egg.js + 搜索服务 + 数据工程 这条链路感兴趣,欢迎继续关注 👋


发布评论

发布评论前请先 登录
取消
0 评论
点赞
收藏

评论列表 0

暂无评论