ElasticSearch经典入门(十) 自动补全功能

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 自动补全功能

前言

今天给大家讲述一下如何简单快速的基于SpringBoot整合ElasticSearch搜索补全功能,该功能是全文检索中很常见的功能,当我们输入关键字,ElasticSearch自动帮我们进行单词联想如下:
image.png

自动补全演示

这里ElasticSearch采用的6.8.6版本,ElasticSearch和Kibana的安装教程请见第一章《ElasticsSearch安装》, 在ES官方文档提供了Completion Suggester实现自动补全功能,需要自动补全的字段类型一定是completion,参与补全查询的字段必须是completion类型。字段的内容可以是用来补全的多个词条形成的数组。下面先使用kibana做一个演示:

第一步,创建索引

PUT goods #创建索引

第二步:创建映射 , 下面给title指定为completion类型,且使用ik_smart分词

PUT goods/_doc/_mapping
{

    "properties": {
      "title": {
        "type": "completion",
        "analyzer" : "ik_smart"
      }
    }
}

第三步:给索引添加文档 ,下面添加了2个文档,title 都是以笔记本开头的内容

PUT goods/_doc/1
{
  "title":"笔记本支架"
}
PUT goods/_doc/2
{
  "title":"笔记本电脑"
}

第四步:执行搜索,通过 suggest 处理补全

GET /goods/_search
{
  "suggest": {
    "title_suggest": {
      "text": "笔记本",
      "completion": {    
        "field": "title",
        "skip_duplicates": true,
        "size": 10
      }
    }
  }
}
  • title_suggest :为 suggest取的一个名字而已
  • text :自动补全的文本前缀
  • field:对哪个字段自动补全
  • skip_duplicates : 跳过重复
  • size :取前10条结果

查询的结果如下
image.png

SpringBoot整合ES完成自动补全

第一步:导入依赖,我采用的SpringBoot版本是2.2.5.RELEASE, pom.xml如下

<parent>
        <groupId> org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

第二步:yaml配置 ,启动类常规写法,配置文件中指向ES地址,如下

server:
  port: 1000
spring:
  elasticsearch:
    rest:
      uris:
        - http://localhost:9200

第三步:编写一个ES的Document对象

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "goods",type = "_doc" ,shards = 1 ,replicas = 0)
public class GoodsDoc {
   
   

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

    @CompletionField(analyzer="ik_smart",searchAnalyzer="ik_smart", maxInputLength = 100)
    private Completion title;

    @Field(type = FieldType.Float)
    private float price;
}

这里把title标记为Completion类型,同时使用了@CompletionField注解指定为自动补全字段。使用IK分词器

第四步:编写repository 对象

@Repository
public interface GoodsRepository extends ElasticsearchRepository<GoodsDoc, String> {
   
   
}

第五步:编写成测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApplicationStarter.class)
public class ESTest {
   
   

    @Autowired
    private ElasticsearchRestTemplate restTemplate;

    @Autowired
    private GoodsRepository repository;


    //创建索引和映射
    @Test
    public void testCreateIndex(){
   
   
        restTemplate.createIndex(GoodsDoc.class);
        restTemplate.putMapping(GoodsDoc.class);

    }

    //添加数据
    @Test
    public void addData(){
   
   
        List<GoodsDoc> orderDocs = new ArrayList<>();

        List<String> suggestList =  new ArrayList<>();
        String title = "笔记本电脑";
        suggestList.add(title); //可以把多个内容作为suggest的数据源
        Completion suggest = new Completion(suggestList.toArray(new String[suggestList.size()]));
        GoodsDoc orderDoc = new GoodsDoc("1", suggest, 100);
        orderDocs.add(orderDoc);

        suggestList =  new ArrayList<>();
        title = "笔记本";
        suggestList.add(title);
        suggest = new Completion(suggestList.toArray(new String[suggestList.size()]));
        orderDoc = new GoodsDoc("2", suggest, 100);
        orderDocs.add(orderDoc);

        suggestList =  new ArrayList<>();
        title = "笔记本支架";
        suggestList.add(title);
        suggest = new Completion(suggestList.toArray(new String[suggestList.size()]));
        orderDoc = new GoodsDoc("3", suggest, 100);
        orderDocs.add(orderDoc);

        suggestList =  new ArrayList<>();
        title = "笔记本内存条";
        suggestList.add(title);
        suggest = new Completion(suggestList.toArray(new String[suggestList.size()]));
        orderDoc = new GoodsDoc("4", suggest, 100);
        orderDocs.add(orderDoc);

        repository.saveAll(orderDocs);
    }
    @Test
    public void search(){
   
   
        // 使用suggest进行标题联想
        CompletionSuggestionBuilder suggest = SuggestBuilders.completionSuggestion("title")
                //根据什么前缀来联想
                .prefix("笔记本")
                // 跳过重复过滤
                .skipDuplicates(true)
                // 匹配数量
                .size(10);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("title-suggest",suggest);

        //执行查询
        SearchResponse suggestResp = restTemplate.suggest(suggestBuilder, GoodsDoc.class);

        //拿到Suggest结果
        Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> orderSuggest = suggestResp
                .getSuggest().getSuggestion("title-suggest");

        // 处理返回结果
        List<String> suggests = orderSuggest.getEntries().stream()
                .map(x -> x.getOptions().stream()
                .map(y->y.getText().toString())
                .collect(Collectors.toList())).findFirst().get();

        // 输出内容
        for (String str : suggests) {
   
   
            System.out.println("自动补全 = " + str);
        }
    }
}

查询效果如下

自动补全 = 笔记本
自动补全 = 笔记本内存条
自动补全 = 笔记本支架
自动补全 = 笔记本电脑

这里是我们根据"笔记本"为前缀联想到的内容,我们把这个结果列表响应给前端就可以做成自动补全的效果了。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
2月前
|
存储 搜索推荐 Java
|
4月前
|
安全 Linux 开发工具
Elasticsearch 搜索入门技术之一
Elasticsearch 搜索入门技术之一
228 1
|
5月前
|
JSON 自然语言处理 数据库
数据库-ElasticSearch入门(索引、文档、查询)
数据库-ElasticSearch入门(索引、文档、查询)
312 0
|
7月前
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
4天前
|
存储 监控 API
Elasticsearch 8.X Rollup 功能详解及避坑指南
Elasticsearch 8.X Rollup 功能详解及避坑指南
11 0
|
3月前
|
存储 关系型数据库 MySQL
ElasticSearch 入门
【2月更文挑战第7天】ElasticSearch 入门 简介 ElasticSearch 的基本概念 ElasticSearch 的查询流程 ElasticSearch 的更新流程
39 2
|
3月前
|
存储 自然语言处理 搜索推荐
ElasticSearch入门篇
ElasticSearch入门篇
|
5月前
|
存储 Java 网络架构
Spring Data Elasticsearch基础入门详解
Spring Data Elasticsearch基础入门详解
132 0
|
5月前
|
存储 数据挖掘 Java
Elasticsearch基础入门与安装部署
Elasticsearch基础入门与安装部署
183 0
|
5月前
|
存储 JSON Java
SpringBoot - 信息检索与ElasticSearch入门
SpringBoot - 信息检索与ElasticSearch入门
37 0

热门文章

最新文章