> 技术文档 > 全文索引and全文检索:Elasticsearch实现“快速定位”

全文索引and全文检索:Elasticsearch实现“快速定位”

目录

一、全文索引:给文本内容建 “关键词目录”

二、全文检索:用 “关键词目录” 快速找内容

三、为什么需要它们?

四、总结:关系与区别

场景需求

技术选型

实现步骤

1. 准备工作

2. 定义商品实体类(映射到 ES 索引)

3. 创建 ES 索引(初始化)

4. 同步商品数据到 ES(建立全文索引)

5. 实现全文检索功能

6. 控制器接收前端请求

效果说明

总结

全文索引(Full-Text Index)和全文检索(Full-Text Search)是信息检索领域的核心概念,常用于高效查询文本内容(如文章、文档、网页等),咱们用通俗的方式聊聊它们的含义和关系。

一、全文索引:给文本内容建 “关键词目录”

想象你有一本厚厚的百科全书,想快速找到包含 “人工智能” 的所有页面,总不能一页页翻吧?这时如果书后有个 “索引表”,专门记录 “人工智能” 这个词出现在哪些页面,就能直接定位 ——全文索引就相当于这个 “智能索引表”

具体来说,全文索引是一种针对文本内容的特殊数据结构,它会提前对文档中的词语(或 “词条”)进行提取、处理(比如去掉 “的、了、the” 等无意义词),然后记录每个词条在哪些文档中出现、出现的位置和频率,最终形成一个 “词条 - 文档” 的映射关系。

举个例子:
假设有 3 篇文档:

  • 文档 1:“猫喜欢吃鱼,猫很可爱”
  • 文档 2:“狗喜欢吃肉,狗很忠诚”
  • 文档 3:“猫和狗是好朋友”

全文索引会处理成类似这样的结构:

猫 → 文档1(出现2次)、文档3(出现1次) 鱼 → 文档1(出现1次) 可爱 → 文档1(出现1次) 狗 → 文档2(出现2次)、文档3(出现1次) 肉 → 文档2(出现1次) 忠诚 → 文档2(出现1次) 好朋友 → 文档3(出现1次) 

有了这个索引,当你想查 “猫” 相关的文档时,直接查索引就能瞬间找到文档 1 和 3,不用再逐字扫描所有文档。

二、全文检索:用 “关键词目录” 快速找内容

有了全文索引,怎么用它查东西?这就是全文检索—— 简单说,就是 “基于全文索引进行的文本查询过程”。

比如你在搜索引擎(如百度)里输入 “秋天的诗句”,搜索引擎会:

  1. 对你输入的关键词 “秋天”“诗句” 进行处理(比如同义词转换,“诗句”→“诗”);
  2. 去全文索引中匹配包含这些关键词的文档(网页);
  3. 根据关键词出现的频率、位置等计算文档相关性(比如关键词在标题里比在段落里更相关);
  4. 把排序后的结果返回给你。

这整个 “输入关键词→匹配索引→返回结果” 的过程,就是全文检索。

三、为什么需要它们?

传统的查询方式(比如数据库的like \'%关键词%\')有个大问题:如果文本量很大(比如几十万篇文档),它会逐字扫描所有内容,速度极慢(就像翻书找词不看索引)。

全文索引 + 全文检索的组合,通过提前建立 “关键词 - 文档” 的映射,把 “逐字扫描” 变成 “索引查表”,查询速度能提升几十甚至上百倍,特别适合:

  • 搜索引擎(百度、谷歌)
  • 文档管理系统(如企业内部的知识库搜索)
  • 电商平台的商品描述搜索(比如搜 “轻薄笔记本”)
  • 日志分析系统(从海量日志中找错误信息)

四、总结:关系与区别

  • 全文索引是 “数据结构”,是基础 —— 相当于 “关键词目录”,用来快速定位文本内容;
  • 全文检索是 “查询过程”,是应用 —— 相当于 “用目录查内容的动作”,依赖全文索引实现。

简单说:先有 “全文索引” 这个 “目录”,才能实现 “全文检索” 这种 “快速找内容” 的能力。

给我举个java后端开发过程中用到全文索引的例子

在 Java 后端开发中,全文索引最常见的场景是实现站内搜索功能,比如电商平台的商品搜索、内容平台的文章搜索等。下面以 “电商平台商品搜索” 为例,详细说明如何结合 Java 技术栈使用全文索引:

场景需求

假设我们开发一个电商平台,需要实现 “商品搜索” 功能:用户输入关键词(如 “轻薄笔记本 红色”),能快速找到商品名称、描述中包含这些关键词的商品,并按相关度排序。

如果直接用数据库的like查询(如where name like \'%轻薄笔记本%\' or desc like \'%轻薄笔记本%\'),会有两个问题:

  1. 性能差:当商品数量达 10 万 + 时,like会全表扫描,查询耗时可能从毫秒级变成秒级;
  2. 功能弱:无法处理同义词(如 “笔记本” 和 “笔记本电脑”)、无法按匹配度排序(如标题含关键词的商品应该排在前面)。

这时就需要用全文索引来解决。

技术选型

Java 后端常用的全文索引方案:

  • Elasticsearch(简称 ES):目前最流行的分布式全文搜索引擎,支持复杂的全文检索、分词、排序等功能,Java 生态有成熟的客户端(如Spring Data Elasticsearch)。
  • 数据库自带全文索引:如 MySQL 的FULLTEXT索引(功能简单,适合小型应用)。

这里以Elasticsearch + Spring Boot为例,展示实现过程。

实现步骤

1. 准备工作
  • 安装 Elasticsearch(本地或服务器部署);
  • 项目引入依赖(pom.xml):

    xml

     org.springframework.boot spring-boot-starter-data-elasticsearch
2. 定义商品实体类(映射到 ES 索引)

用注解定义商品与 ES 索引的映射关系,指定哪些字段需要被全文索引:

@Data@Document(indexName = \"product\") // 对应ES中的\"product\"索引(类似数据库表)public class Product { @Id // 主键 private Long id; // 商品名称:分词索引,权重设为2(匹配时优先级更高) @Field(type = FieldType.Text, analyzer = \"ik_max_word\", searchAnalyzer = \"ik_smart\", fields = @InnerField(type = FieldType.Keyword, name = \"keyword\")) private String name; // 商品描述:分词索引,权重默认1 @Field(type = FieldType.Text, analyzer = \"ik_max_word\", searchAnalyzer = \"ik_smart\") private String description; // 商品分类:不分词,精确匹配(如\"笔记本电脑\"作为整体) @Field(type = FieldType.Keyword) private String category; // 价格、库存等字段(无需全文索引,用于过滤/排序) private BigDecimal price; private Integer stock;}
  • analyzer = \"ik_max_word\":使用 IK 分词器(中文分词专用),对字段内容进行细粒度分词(如 “轻薄笔记本”→“轻薄”“笔记本”“轻薄笔记本”);
  • Text类型:会被分词并建立全文索引;
  • Keyword类型:不分词,适合精确匹配(如按分类筛选)。
3. 创建 ES 索引(初始化)

启动项目时,Spring Data Elasticsearch 会根据@Document注解自动创建 ES 索引,也可以手动通过 API 创建:

@Autowiredprivate ElasticsearchOperations elasticsearchOperations;// 初始化索引(项目启动时执行)@PostConstructpublic void initIndex() { // 判断索引是否存在,不存在则创建 if (!elasticsearchOperations.indexOps(Product.class).exists()) { elasticsearchOperations.indexOps(Product.class).create(); }}
4. 同步商品数据到 ES(建立全文索引)

当商品新增 / 修改时,需要同步到 ES,让 ES 构建全文索引:

@Servicepublic class ProductService { @Autowired private ProductRepository productRepository; // Spring Data的Repository接口 // 新增商品时同步到ES public void addProduct(Product product) { // 1. 保存到MySQL数据库(省略代码) // 2. 同步到ES,ES会自动为name、description等字段建立全文索引 productRepository.save(product); }}

此时 ES 会对namedescription字段进行分词,并生成类似这样的索引结构(简化版):

\"轻薄\" → 商品1(name中出现)、商品3(description中出现) \"笔记本\" → 商品1(name中出现)、商品2(name中出现) \"红色\" → 商品1(name中出现)、商品4(description中出现) ...
5. 实现全文检索功能

用户输入关键词后,通过 ES 查询匹配的商品,并按相关度排序:

@Servicepublic class SearchService { @Autowired private ElasticsearchRestTemplate esTemplate; public Page searchProducts(String keyword, int page, int size) { // 1. 构建查询条件:匹配name或description中包含关键词的商品 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 2. 全文检索:对name和description字段进行匹配,name权重更高 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() // name字段匹配,权重*2 .should(QueryBuilders.matchQuery(\"name\", keyword).boost(2.0f)) // description字段匹配,权重默认1 .should(QueryBuilders.matchQuery(\"description\", keyword)); queryBuilder.withQuery(boolQuery); // 3. 分页设置 queryBuilder.withPageable(PageRequest.of(page, size)); // 4. 执行查询,ES会根据全文索引快速匹配,并按相关度排序 SearchHits hits = esTemplate.search( queryBuilder.build(), Product.class ); // 5. 处理结果(转换为Page对象) List products = hits.stream() .map(SearchHit::getContent) .collect(Collectors.toList()); return new PageImpl(products, PageRequest.of(page, size), hits.getTotalHits()); }}
6. 控制器接收前端请求
@RestController@RequestMapping(\"/search\")public class SearchController { @Autowired private SearchService searchService; // 用户输入关键词查询商品 @GetMapping public Page search(@RequestParam String keyword, @RequestParam(defaultValue = \"0\") int page, @RequestParam(defaultValue = \"10\") int size) { return searchService.searchProducts(keyword, page, size); }}

效果说明

当用户输入 “轻薄笔记本 红色” 时:

  1. ES 会对关键词分词(“轻薄”“笔记本”“红色”);
  2. 从全文索引中匹配所有包含这些词的商品;
  3. 按匹配度排序(如标题含 “轻薄笔记本” 且描述含 “红色” 的商品排在最前);
  4. 毫秒级返回结果(即使商品数量达百万级)。

总结

这个例子中,Elasticsearch 负责维护全文索引(对商品名称、描述分词并建立映射),Java 后端通过 Spring Data Elasticsearch 操作 ES 实现全文检索,最终高效解决了电商平台的商品搜索需求。类似的场景还有:

  • 博客平台的文章搜索(按标题、内容检索);
  • 企业 CRM 系统的客户信息搜索(按公司名、备注检索);
  • 日志管理系统的错误日志检索(按关键词定位问题)。

龙川教育网