文档目录
商品搜索接口

简介

本接口文档面向电商应用开发者,提供“商品搜索”能力的完整接口参考。当前仓库实现了统一的站内搜索入口,支持按关键词检索、模块筛选(如商品)、分类筛选、分页与排序等能力;同时提供了商品列表的独立接口,支持品牌筛选与排序。本文档将基于源码梳理:

  • 搜索接口的 HTTP 方法、URL 路径与参数规范
  • 搜索算法覆盖范围(标题/描述/内容匹配、多语言标题匹配)
  • 高级筛选(分类、品牌)与排序(销量、价格、更新时间、自定义排序)
  • 搜索结果结构与分页
  • 请求与响应示例
  • 性能优化建议

项目结构

搜索相关代码主要分布在以下位置:

  • API 路由与控制器:定义 /api/?route=search 的 GET 搜索接口
  • 前台服务与模型:实现跨模块 UNION 查询、分页、排序选项构建与结果格式化
  • 商品服务:提供商品列表与详情能力,包含品牌筛选与排序
graph TB
Client["客户端"] --> Route["API 路由<br/>search.php"]
Route --> Ctl["SearchController<br/>index()"]
Ctl --> Svc["SearchService<br/>buildSearchResultData()"]
Svc --> Sort["ListSortOptionBuilder<br/>buildSortOptions()"]
Svc --> Model["Search<br/>buildUnionSearchQuery()/fetchUnionSearchRows()"]
Model --> DB["数据库"]

核心组件

  • API 路由:声明 search 路由,映射到 SearchController::index
  • API 控制器:接收 q、module、category_id、page、by、sort 等参数,调用服务层并返回统一 JSON
  • 搜索服务:组装查询、排序、分页与结果格式化
  • 搜索模型:按模块动态生成 UNION ALL 查询,支持标题/内容/多语言标题匹配与分类过滤
  • 排序构建器:根据配置与传入 by/sort 生成前端排序项与 SQL 片段
  • 商品服务:提供商品列表与详情,支持品牌筛选与排序

架构总览

搜索流程从 API 路由进入,控制器校验参数后交由服务层处理。服务层根据是否指定 module 决定搜索范围;若为 product 则启用商品专属排序;最终通过模型层执行 UNION 查询并分页返回。

sequenceDiagram
participant C as "客户端"
participant R as "路由"
participant Ctrl as "SearchController"
participant S as "SearchService"
participant M as "Search 模型"
participant D as "数据库"
C->>R : GET /api/?route=search&q=...&module=product&category_id=...&page=...&by=...&sort=...
R->>Ctrl : index(request)
Ctrl->>Ctrl : 校验 q/module/category_id/page/by/sort
Ctrl->>S : buildSearchResultData(keyword, module, catId, page, sortBy, sortDir)
S->>S : 计算排序选项与SQL
S->>M : buildUnionSearchQuery(...)
M->>D : 执行UNION查询(标题/内容/多语言标题匹配)
D-->>M : 结果集
M-->>S : 分页数据(list, pager)
S-->>Ctrl : 格式化后的search_list与元信息
Ctrl-->>C : ApiResponse.success(data)

详细组件分析

搜索接口规范

  • HTTP 方法:GET
  • URL 路径:/api/?route=search
  • 必需/可选参数:
    • q:搜索关键词(字符串,空表示不限)
    • module:限定模块,如 product(字母,未传或非法时回退默认)
    • category_id:分类 ID(整数,0 表示不限)
    • page:页码(整数,默认 1)
    • by:排序字段(字符串,如 sales/price/created_at/sort)
    • sort:排序方向(asc/desc,仅对可切换字段生效)
  • 响应格式:统一成功包装,data 中包含 title、keyword、search_module、search_results、search_list、sort_list 等

搜索算法与匹配范围

  • 关键词匹配:
    • 单语言模式:在标题与内容中模糊匹配(LIKE %keyword%)
    • 多语言模式:关联 language_value,按标题译文进行 LIKE 匹配
  • 模块范围:
    • 未指定 module:按配置的 column_module 列表进行 UNION ALL 合并
    • 指定 module:仅在该模块内检索(例如 product)
  • 分类筛选:
    • 当 category_id > 0 时,限定在该分类及其子分类内
  • 状态过滤:
    • 若表存在 status 字段,则只取 status = 1 的记录
flowchart TD
Start(["开始"]) --> CheckQ["检查关键词是否为空"]
CheckQ --> |为空| ListMode["无关键词列表模式"]
CheckQ --> |非空| BuildQuery["按模块构建子查询"]
BuildQuery --> Lang{"是否开启多语言?"}
Lang --> |是| MatchTitleLang["按language_value.title匹配"]
Lang --> |否| MatchTitleContent["按title/content匹配"]
MatchTitleLang --> CatFilter{"是否指定分类?"}
MatchTitleContent --> CatFilter
CatFilter --> |是| Subtree["获取子分类ID集合并whereIn"]
CatFilter --> |否| StatusCheck{"是否存在status字段"}
Subtree --> StatusCheck
StatusCheck --> |是| FilterStatus["where status=1"]
StatusCheck --> |否| UnionAll["UNION ALL合并各模块"]
FilterStatus --> UnionAll
UnionAll --> Order["应用排序SQL"]
Order --> End(["结束"])

高级搜索选项

  • 分类筛选:通过 category_id 限定至该分类及子分类
  • 品牌筛选:商品列表接口支持 brand_id 参数(见商品列表接口)
  • 评分筛选:当前搜索接口未暴露评分筛选参数
  • 价格区间筛选:当前搜索接口未暴露价格区间参数

说明:

  • 搜索接口本身不直接支持价格区间与评分筛选;如需此类能力,可在上层封装或在商品列表接口中组合使用
  • 品牌筛选可通过商品列表接口实现,再结合业务逻辑形成“搜索+筛选”的组合体验

排序功能

  • 支持的排序字段:sales(销量)、price(价格)、created_at(发布时间)、sort(自定义排序)
  • 排序方向:
    • price 字段支持 asc/desc 切换
    • 其他字段默认方向由构建器决定
  • 默认排序:created_at DESC, id DESC(搜索);商品列表默认 sort ASC, id DESC
  • 排序选项构建:
    • 根据配置 features.order 决定是否暴露销量排序
    • 生成前端排序项与对应 SQL 片段
classDiagram
class ListSortOptionBuilder {
+buildSortOptions(fields, options, default_sort, by, sort, page_url, table_alias) array
}
class SearchService {
+buildSearchResultData(keyword, searchModule, catId, page, sortBy, sortDir) array
}
class ProductService {
+buildProductListData(catId, page, pageSize, brandId, sortBy, sortDir, archive, isApi, userId, allCategories) array
}
SearchService --> ListSortOptionBuilder : "使用"
ProductService --> ListSortOptionBuilder : "使用"

搜索结果结构

  • search_list:当前页结果数组,每项包含 id、module、name/title、price、image/thumbnail、created_at、description、url、cate_info 等
  • pager:分页信息(list、pager 键结构来自底层分页)
  • sort_list:排序选项数组(用于前端渲染)
  • keyword、search_module、title、search_results:页面级元信息

请求与响应示例

  • 请求示例(搜索商品):
    • GET /api/?route=search&q=手机&module=product&category_id=10&page=1&by=price&sort=asc
  • 响应示例(简化):
    • code: 200
    • data:
      • title: “搜索结果”
      • keyword: “手机”
      • search_module: “product”
      • search_results: “找到 X 个结果”
      • search_list: [...]
      • sort_list: [...]

说明:

  • 以上为基于源码行为的示例化描述;实际字段以服务端返回为准

智能搜索(建议与热门搜索)

  • 当前仓库未实现独立的“搜索建议”或“热门搜索词”接口
  • 可在现有搜索接口基础上扩展:
    • 缓存高频关键词并返回 top N
    • 基于用户历史或全站统计生成建议
  • 建议作为后续增强点,不在本次版本范围内

依赖关系分析

  • 路由依赖控制器:search 路由绑定 SearchController::index
  • 控制器依赖服务:SearchController 注入 SearchService
  • 服务依赖排序构建器与模型:SearchService 使用 ListSortOptionBuilder 生成排序 SQL,使用 Search 模型构建 UNION 查询
  • 模型依赖数据库:Search 模型通过 ORM 构造子查询并执行分页
graph LR
Route["search.php"] --> Controller["SearchController.php"]
Controller --> Service["SearchService.php"]
Service --> Sort["ListSortOptionBuilder.php"]
Service --> Model["Search.php"]
Model --> DB["数据库"]

性能考虑

  • 查询优化
    • 使用 UNION ALL 合并多模块结果,避免重复扫描
    • 仅在必要时关联 language_value 表进行多语言标题匹配
    • 分类筛选通过子树 ID 列表 with inWhere 减少全表扫描
  • 索引建议
    • 为标题、内容、创建时间、分类 ID 建立合适索引以提升 LIKE 与排序效率
    • 对频繁排序字段(如 created_at、price)建立索引
  • 分页与限流
    • 合理设置每页条数(search 专用 > product > article > 默认 10)
    • 对搜索接口实施限流策略,防止恶意高频请求
  • 缓存策略
    • 对热门搜索词与热门分类结果进行短期缓存
    • 对静态排序选项与分类树进行缓存

故障排查指南

  • 关键词校验失败
    • 现象:抛出领域异常,提示关键词无效
    • 原因:q 参数未通过关键字校验规则
    • 处理:检查输入是否符合规则,或清空关键词重试
  • 模块名非法
    • 现象:module 非字母或未在允许列表中,将被忽略或置空
    • 处理:确保 module 为合法字母串且在配置的 column_module 中
  • 分类不存在或无效
    • 现象:category_id 无法解析或无子分类
    • 处理:确认分类 ID 有效;若为 0 或不传则不限分类
  • 排序参数错误
    • 现象:by/sort 不合法导致回退默认排序
    • 处理:使用支持的字段与方向(如 by=sales&sort=desc)

结论

当前仓库提供了统一的站内搜索入口,支持关键词搜索、模块与分类筛选、分页与排序,并在商品场景下支持品牌筛选与多种排序方式。对于价格区间与评分筛选、搜索建议与热门搜索等功能,可在现有基础上进行扩展。建议在上线前完善索引与缓存策略,并结合限流保障稳定性。

附录

接口清单

  • 站内搜索
    • 方法:GET
    • 路径:/api/?route=search
    • 参数:q、module、category_id、page、by、sort
    • 响应:统一成功包装,data 包含搜索列表与元信息
  • 商品列表(辅助筛选)
    • 方法:GET
    • 路径:/api/?route=product
    • 参数:id/category_slug、brand_id、by、sort、page 等
    • 响应:商品列表、分页、排序选项、品牌信息
添加日期:2026-10-05