微服务——ES实现自动补全

news2025/4/9 19:38:41

效果展示

在搜索框根据拼音首字母进行提示

 

 

拼音分词器

和IK中文分词器一样的用法,按照下面的顺序执行。 

# 进入容器内部
docker exec -it elasticsearch /bin/bash
 
# 在线下载并安装
./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.12.1/elasticsearch-analysis-pinyin-7.12.1.zip
 
#退出
exit
#重启容器
docker restart elasticsearch

重启完成之后进行拼音分词可以看见每个字都有,以及整个词语首字母组合成的一个。

 自定义分词器

只用默认的功能还远远不够。

先用ik进行分词,再用拼音分词器分

 

PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": { 
        "my_analyzer": { 
          "tokenizer": "ik_max_word",
          "filter": "py"
        }
      },
      "filter": {
        "py": { 
          "type": "pinyin",
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name":{
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

 在test这份索引库当中再次测试就可以看见既有中文也有拼音分词了。

POST /test/_analyze
{
  "text":["北岭山脚鼠鼠"],
  "analyzer": "my_analyzer"
}

 但是这里还会有问题,用中文搜索时会把同音字也一起搜索到

指定搜索时和创建时用不同的分词器

 在上面的语句里面加上了一条

        "search_analyzer": "ik_smart"

 

POST /test/_doc/1
{
  "id": 1,
  "name": "狮子"
}
POST /test/_doc/2
{
  "id": 2,
  "name": "虱子"
}

GET /test/_search
{
  "query": {
    "match": {
      "name": "掉入狮子笼咋办"
    }
  }
}

 结果如下

 DSL实现自动补全查询

查询补全语法

 数据准备

// 自动补全的索引库
PUT test2
{
  "mappings": {
    "properties": {
      "title":{
        "type": "completion"
      }
    }
  }
}
// 示例数据
POST test2/_doc
{
  "title": ["Sony", "WH-1000XM3"]
}
POST test2/_doc
{
  "title": ["SK-II", "PITERA"]
}
POST test2/_doc
{
  "title": ["Nintendo", "switch"]
}

 查询语句

// 自动补全查询
GET /test2/_search
{
  "suggest": {
    "title_suggest": {
      "text": "s", // 关键字
      "completion": {
        "field": "title", // 补全字段
        "skip_duplicates": true, // 跳过重复的
        "size": 10 // 获取前10条结果
      }
    }
  }
}

 

 酒店数据自动补全

修改酒店索引库数据结构

DELETE /hotel
# 酒店数据索引库
PUT /hotel
{
  "settings": {
    "analysis": {
      "analyzer": {
        "text_anlyzer": {
          "tokenizer": "ik_max_word",
          "filter": "py"
        },
        "completion_analyzer": {
          "tokenizer": "keyword",
          "filter": "py"
        }
      },
      "filter": {
        "py": {
          "type": "pinyin",
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart"
      },
      "suggestion":{
          "type": "completion",
          "analyzer": "completion_analyzer"
      }
    }
  }
}

先删除再重新创建一个

然后在HotelDoc这个实体类里面新增一个字段suggestion,这个字段是由现有的字段组成放进去。

private List<String> suggestion;
this.suggestion= Arrays.asList(this.brand,this.business);

然后重新执行之前的批量插入的语句

 再次测试搜索可以看见搜索得到的结果里面多出了品牌和商圈信息。 

 但是这里business字段有可能是由多个的,要进行切割。

修改HotelDoc上面的构造方法的代码

        if(this.business.contains("、")){
            //business有多个值,需要切割
            String[] arr = this.business.split("、");
            //添加元素
            this.suggestion=new ArrayList<>();
            this.suggestion.add(this.brand);
            Collections.addAll(this.suggestion,arr);
        }else {
            this.suggestion = Arrays.asList(this.brand, this.business);
        }

再次插入数据可以看见多个词条已经分开了。 

 

 进行搜索测试

搜索所有以h开头的词条

 RestAPI实现自动补全

 请求组装+响应解析

    @Test
    void testSuggest() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSl
        request.source().suggest(new SuggestBuilder().addSuggestion(
                "suggestion",
                SuggestBuilders.completionSuggestion("suggestion")
                        .prefix("h")
                        .skipDuplicates(true)
                        .size(10)
        ));
        //3.发起请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析结果
        Suggest suggest= response.getSuggest();
        //4.1根据补全查询名称,获取补全结果
        CompletionSuggestion suggestions = suggest.getSuggestion("suggestion");
        //4.2获取options
        List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
        //4.3遍历
        for (CompletionSuggestion.Entry.Option option : options) {
            String text = option.getText().toString();
            System.out.println(text);
        }
    }

 实现搜索框自动补全

Controller中

    @GetMapping("suggestion")
    public List<String>getSuggestion(@RequestParam("key")String prefix){
        return hotelService.getSuggestions(prefix);
    }

Service中

    @Override
    public List<String> getSuggestions(String prefix) {
        try {
            //1.准备request
            SearchRequest request = new SearchRequest("hotel");
            //2.准备DSl
            request.source().suggest(new SuggestBuilder().addSuggestion(
                    "suggestion",
                    SuggestBuilders.completionSuggestion("suggestion")
                            .prefix(prefix)
                            .skipDuplicates(true)
                            .size(10)
            ));
            //3.发起请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //4.解析结果
            Suggest suggest= response.getSuggest();
            //4.1根据补全查询名称,获取补全结果
            CompletionSuggestion suggestions = suggest.getSuggestion("suggestion");
            //4.2获取options
            List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
            //4.3遍历
            List<String>list=new ArrayList<>(options.size());
            for (CompletionSuggestion.Entry.Option option : options) {
                String text = option.getText().toString();
                list.add(text);
            }
            return list;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

效果演示

成功根据提示进行查询

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/849866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

迭代器模式-遍历聚合对象中的元素

在开发中&#xff0c;我们经常使用到Iterator这个接口&#xff0c;我们很疑惑于这个接口的作用&#xff0c;认为集合已经实现了数据访问的方法&#xff0c;增加Iterator的意义在哪。本文我们将学习迭代器模式&#xff0c;用以探讨Iterator的作用。 1.1 迭代器模式概述 提供一…

地图 SDK gitlab 测试代码环境配置

文章目录 1、Gradle 插件版本和 Gradle 版本2、NDK 路径3、JDK 版本4、修改变量5、重新 BuildQ&A&#xff1a; test 用例启动之后问题问题描述 拉下项目的 dev 分支&#xff0c;然后依赖的 mapsdk-base 也完成下载 &#xff0c;之后就是Android Studio 配置环境 1、Gradle …

【Git】保姆级详解:Git配置SSH Key(密钥和公钥)到github

博主简介&#xff1a;22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a;是瑶瑶子啦每日一言&#x1f33c;: “当人们做不到一些事情的时候&#xff0c;他们会对你说你也同样不能。”——《当幸福来敲门》 克里斯加德纳 Git配置SSH Key 一、什么是Git?二、什么…

如何给Google Chrome增加proxy

1. 先打开https://github.com/KaranGauswami/socks-to-http-proxy/releases 我的电脑是Liunx系统所以下载第一个 2. 下载完之后把这个文件变成可执行文件&#xff0c;可以是用这个命令 chmod x 文件名 3. 然后执行这个命令&#xff1a; ./sthp-linux -p 8080 -s 127.0.0.1:…

Jwt(Json web token)——使用token的权限验证方法 用户+角色+权限表设计 SpringBoot项目应用

目录 引出使用token的权限验证方法流程 用户、角色、权限表设计权限表角色表角色-权限关联表用户表查询用户的权限&#xff08;四表联查&#xff09;数据库的视图 项目中的应用自定义注解拦截器controller层DTO返回给前端枚举类型的json化日期json问题 实体类-DAO 总结 引出 1.…

学习pytorch

学习pytorch 1. 环境安装配置镜像源conda命令记录遇到的问题1. torch.cuda.is_available() False 1. 环境安装 B站小土堆视频 配置镜像源 conda config --show channels conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/mainhttp://www.m…

leetcode 图算法小结

文章目录 1 DFS和BFS797. 所有可能的路径200. 岛屿数量 1 DFS和BFS 深度优先遍历一般采用回溯算法进行解决。回溯算法&#xff0c;其实就是dfs的过程。 void dfs(参数) {处理节点dfs(图&#xff0c;选择的节点); // 递归回溯&#xff0c;撤销处理结果 }广度优先搜索理解为层次…

Java-数据类型

数据类型 数据类型基本数据类型整形浮点字符型布尔类字节 引用数据类型类型转换显式转换隐式转换注意事项 整型提升 作为学习Java的入门知识,在刚开始面试的几场,表现不太好的时候,就有几个面试官会问这个问题,估计此时此刻我在他们的心目中也就是这个问题的层次了吧…当然,当时…

Linux网络服务之自动装机(PXE+KICKSTART)详解

自动装机 一、启动操作系统的方式1.1 系统装机的三种引导方式1.2 系统安装过程1.3 三大文件1.4 如何实现自动装机&#xff1f; 二、PXE2.1 PXE的简介和优点2.2 实现PXE的前提条件2.3 PXE实现过程2.5 要安装的服务2.6 实现PXE2.6.1 前置准备2.6.2 安装并配置DHCP2.6.3 安装并配置…

Nginx负载均衡搭建

目录 1、准备一台装有nginx服务的主机 2、所需模块说明&#xff1a; 3、两台Web服务器主机 4、 修改nginx的配置文件 5、查看结果&#xff1a; 1、准备一台装有nginx服务的主机 LVS—DR集群的搭建_.98℃的博客-CSDN博客 2、所需模块说明&#xff1a; Nginx http 功能模…

【音视频】vms布署说明

目录 外场布署场景&#xff08;99%&#xff09; 研发实验场景&#xff08;1%&#xff09; 高级玩法 证书安装方法 外场布署场景&#xff08;99%&#xff09; 下面两种场景&#xff0c;为本产品主要应用场景&#xff0c;2023-08-08日后&#xff08;统一所有证书&#xff09;…

入门平台工程的福音,麦肯锡刚发布了平台工程蓝图

在软件开发和工程效能领域&#xff0c;平台工程 (Platform Engineering) 是继 DevOps 后逐渐兴起的主流概念。平台工程&#xff0c;顾名思义&#xff0c;就是通过组合一系列标准化的软件开发工具&#xff0c;构建起一个标准化的研发平台。目标则是为了提高开发者体验和生产力。…

构建Docker容器监控系统 (1)(Cadvisor +InfluxDB+Grafana)

目录 Cadvisor InfluxDBGrafana 1. Cadvisor 2.InfluxDB 3.Grafana 开始部署&#xff1a; 下载组件镜像 创建自定义网络 创建influxdb容器 创建数据库和数据库用户 创建Cadvisor 容器 准备测试镜像 创建granafa容器 访问granfana 添加数据源 Add data source 新建 …

python接口自动化之自动发送测试报告邮件

前言 ​ SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;也就是简单邮件传输协议&#xff0c;是一种提供可靠且有效电子邮件传输的协议。python的smtplib模块就提供了一种很方便的途径发送电子邮件&#xff0c;它对smtp协议进行了简单的封装。 ​ python发邮件主…

四 、Mysql 开发

四 、Mysql开发 102 可以使用MySQL直接存储文件吗&#xff1f; 可以使用 BLOB (binary large object)&#xff0c;用来存储二进制大对象的字段类型。 TinyBlob 255 值的长度加上用于记录长度的1个字节(8位) Blob 65K值的长度加上用于记录长度的2个字节(16位) MediumBlob 16M值…

AutoJS自定义悬浮菜单(附完整代码)

我们在开发Autojs脚本时&#xff0c;需要使用到悬浮窗功能来控制脚本。那么到底要如何来做呢&#xff1f;今天给大家分享一些&#xff0c;先来看看效果&#xff1a; 调整移动和贴边。 防止滑出屏幕 附上完整代码 var storage storages.create("日赚3万_短视频合集&quo…

以Java的方式将文件上传到阿里云OSS

文章目录 1. 开通对象存储服务2. 创建 AccessKey 密钥3. 通用代码实现 1. 开通对象存储服务 控制台 → 对象存储 OSS → 立即开通 Bucket列表 → 点击创建 Bucket 填写名称、地域&#xff0c;名称创建后不可修改&#xff0c;地域选择最近的&#xff0c;存储类型选择标准存储&…

OpenCV: 对“google::protobuf::internal::Release_CompareAndSwap”的未定义

解决办法&#xff1a; 需要在文件 protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h 中的以下补丁 inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, Atomic64 old_value, …

Ajax-AJAX请求的不同发送方式

&#x1f954;&#xff1a;你一定能成为想要成为的人 发送AJAX请求不同方式 发送AJAX请求不同方式1、jQuery发送AJAX请求2、axios发送AJAX请求&#xff08;重点&#xff09;3、fetch发送AJAX请求 发送AJAX请求不同方式 1、jQuery发送AJAX请求 首先需要jquery的js文件&#xf…

Linux shell yes命令(不停输出换行的y)(不停输出换行的指定字符串)(脚本自动确认y)

文章目录 yes命令功能doc文档英文中文翻译完整文档 示例应用案例自动为脚本多次确认y yes命令功能 yes命令可以不断地输出换行的指定字符串&#xff0c;不加参数时&#xff0c;不断输出换行的“y”&#xff0c;有时我们需要执行一些需要用户键入“y”确认的脚本&#xff0c;但…