易君召
易君召
发布于 2026-07-19 / 13 阅读
0
0

Elasticsearch 全文检索完整实操教程

一、前置基础

1. 核心概念

  • 索引 (index):类似数据库表

  • 文档 (document):类似数据库行,JSON 格式

  • 字段 (field):类似数据库列

  • 分词器 (analyzer):全文检索核心,把中文 / 英文拆成词条用于匹配

  • 倒排索引:ES 底层结构,实现高速全文模糊、关键词匹配

2. 环境准备

  1. 安装 ES 8.x(推荐)+ Kibana(可视化操作)

  2. 中文分词必备插件:elasticsearch-analysis-ik(IK 分词,中文检索刚需)

  3. 端口默认:ES 9200,Kibana 5600

二、第一步:创建带中文分词的索引(全文检索关键)

默认分词对中文极不友好,必须指定 IK 分词器,执行 Kibana DevTools 请求:

json

PUT /article
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1,
    "analysis": {
      "analyzer": {
        "ik_max_word": {
          "type": "ik_max_word"
        },
        "ik_smart": {
          "type": "ik_smart"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id": {"type": "integer"},
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "author": {"type": "keyword"},
      "create_time": {"type": "date"}
    }
  }
}

分词说明

  • text:可分词,用于全文检索(标题、内容)

  • keyword:不分词,精确匹配(作者、标签)

  • ik_max_word:拆分所有细词,索引用,召回更多结果

  • ik_smart:粗粒度分词,搜索用,精准度更高

三、第二步:写入测试文档(数据)

单条插入

POST /article/_doc/1
{
  "id": 1,
  "title": "Elasticsearch全文检索实战教程",
  "content": "本文讲解ES实现中文全文检索,包含分词、模糊搜索、高亮、分页功能",
  "author": "张三",
  "create_time": "2026-07-19"
}

批量插入多条

json

POST /article/_bulk
{"index":{"_id":2}}
{"id":2,"title":"Java开发搜索引擎实践","content":"使用Elasticsearch搭建项目全文检索系统","author":"李四","create_time":"2026-07-18"}
{"index":{"_id":3}}
{"id":3,"title":"Mysql与ES数据同步方案","content":"数据库数据同步到ES,实现商品全文检索","author":"张三","create_time":"2026-07-17"}

四、核心:各类全文检索语法(Kibana 可直接运行)

1. match 单字段全文检索(最常用)

对字段分词后模糊匹配关键词,自动分词中文

需求:查询标题包含 全文检索

json

GET /article/_search
{
  "query": {
    "match": {
      "title": "全文检索"
    }
  }
}

2. multi_match 多字段同时检索(标题 + 内容一起搜)

搜索词同时匹配 title、content,适合通用搜索框

json

GET /article/_search
{
  "query": {
    "multi_match": {
      "query": "ES全文检索",
      "fields": ["title", "content"]
    }
  }
}

加权提升标题权重(标题匹配优先展示):

json

"fields": ["title^3", "content"]

^3 代表标题分值 ×3,排序更靠前

3. match_phrase 短语精确匹配(连续词语)

要求关键词连续出现,比如搜 ES全文检索,只会匹配连续词组

json

GET /article/_search
{
  "query": {
    "match_phrase": {
      "content": "ES全文检索"
    }
  }
}

4. 模糊检索 fuzziness(错别字容错)

输入错字也能搜到,比如搜 Elasticseach 匹配 Elasticsearch

json

GET /article/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Elasticseach",
        "fuzziness": 1
      }
    }
  }
}

fuzziness:1 允许 1 个字符误差

5. 组合检索(全文检索 + 精确过滤)

场景:全文搜 ES,同时筛选作者张三

GET /article/_search
{
  "query": {
    "bool": {
      "must": [
        {"multi_match": {"query": "ES", "fields": ["title","content"]}}
      ],
      "filter": [
        {"term": {"author": "张三"}}
      ]
    }
  }
}
  • must:必须匹配(全文检索,算相关性得分)

  • filter:过滤条件,不影响打分,性能更好

五、实用增强功能

1. 检索结果关键词高亮(前端标红)

GET /article/_search
{
  "query": {
    "multi_match": {
      "query": "全文检索",
      "fields": ["title","content"]
    }
  },
  "highlight": {
    "fields": {
      "title": {},
      "content": {}
    },
    "pre_tags": "<span style='color:red'>",
    "post_tags": "</span>"
  }
}

返回结果会携带带红色标签的关键词文本,前端直接渲染

2. 分页 + 排序

  • from:偏移量

  • size:每页条数

  • _score:全文相关性分数(默认按分数降序)

GET /article/_search
{
  "from": 0,
  "size": 2,
  "sort": [{"_score": "desc"}],
  "query": {
    "match": {"content": "检索"}
  }
}

3. 关键词前缀搜索(搜索框输入联想)

输入 elas 匹配 Elasticsearch

GET /article/_search
{
  "query": {
    "prefix": {
      "title.keyword": "Elas"
    }
  }
}

六、Java SpringBoot 代码实现(业务开发常用)

1. Maven 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2. application.yml 配置

spring:
  elasticsearch:
    uris: http://127.0.0.1:9200

3. 实体类映射索引

import org.springframework.data.elasticsearch.annotations.*;
import java.util.Date;

@Document(indexName = "article")
public class Article {
    @Id
    private Integer id;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String content;

    @Field(type = FieldType.Keyword)
    private String author;

    @Field(type = FieldType.Date)
    private Date createTime;
    // getter/setter
}

4. Repository 层

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface ArticleRepo extends ElasticsearchRepository<Article, Integer> {
}

5. Service 全文检索逻辑

import co.elastic.clients.elasticsearch._types.query_dsl.MultiMatchQuery;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SearchService {
    @Resource
    private ElasticsearchTemplate template;

    // 多字段全文检索
    public List<Article> search(String keyword) {
        MultiMatchQuery match = MultiMatchQuery.of(m -> m
                .query(keyword)
                .fields("title^3", "content")
        );

        SearchResponse<Article> resp = template.search(s -> s
                .index("article")
                .query(q -> q.multiMatch(match)), Article.class);

        List<Article> list = new ArrayList<>();
        for (Hit<Article> hit : resp.hits().hits()) {
            list.add(hit.source());
        }
        return list;
    }
}

七、常见优化要点

  1. 中文必须装 IK 分词,否则中文单字拆分,检索效果极差

  2. 区分 text(检索)和 keyword(精确筛选、聚合)

  3. 大数据分页避免 from+size,使用 search_after 深度分页

  4. 不需要打分的过滤条件放 filter,提升查询性能

  5. 热点索引合理设置分片副本,写入量大时分片数调大

  6. 商品 / 文章类业务,可增加 boost 权重控制排序优先级

八、常见问题

  1. 搜中文无结果:未安装 IK、mapping 没指定 ik 分词器

  2. 匹配结果太多:改用 match_phrase 短语检索缩小范围

  3. 搜索速度慢:字段过多、分片不合理、未加过滤条件


评论