ElasticSearch 自动补全

1、前言

当用户在搜索框输入字符时,我们应该提示出与该字符有关的搜索项,根据用户输入的字母,提示完整词条的功能,就是自动补全。

2、安装拼音分词器

Github地址:https://github.com/infinilabs/analysis-pinyin
插件下载地址:https://release.infinilabs.com/analysis-pinyin/stable/

2.1 根据 ES 版本下载指定的插件包

在这里插入图片描述

2.2 安装步骤

  1. 下载插件并解压,重命名为:analysis-pinyin
  2. 上传 analysis-pinyin 到 es 的 plugin 目录
  3. 重启 es
  4. 测试

2.3 测试

DSL语法:

POST /_analyze
{"text":"刘德华","analyzer":"pinyin"
}

测试结果:
在这里插入图片描述

3、自定义分词器

默认的拼音分词器会将每个汉字单独分为拼音。我们希望的是每个词条形成一组拼音,需要对拼音分词器做个性化定制,形成自定义分词器。

3.1 ES 分词器(analyzer)组成部分:

  • 字符过滤器(Character Filters):它主要用于在分词之前对原始文本进行预处理。这一步骤可以对文本进行清洗、转换等操作,例如去除 HTML 标签、转换字符大小写、处理特殊字符等。
  • 分词器(Tokenizer):分词器负责将经过字符过滤器处理后的文本按照一定的规则分解为单个的词元(Token)。这些规则可以基于空格、标点符号等进行分词,不同的分词器有不同的分词策略。例如,standard 分词器会按照空格和标点符号来划分词元,将文本拆分成一个个独立的单词或符号。
  • 词元过滤器(Token Filters):词元过滤器用于对分词器产生的词元进行进一步的处理。这可以包括过滤掉停用词(如 “的”、“是” 等在某些情况下对搜索意义不大的词)、词形还原(将词元还原为其基本形式,如将 “running” 还原为 “run”)、同义词替换(将一个词元替换为其同义词,如将 “电脑” 替换为 “计算机”)等操作。

3.2 执行流程图

在这里插入图片描述
说明:特殊符号准换成指定的中文字符,然后借助 ik_smart 进行分词,再通过 pinyin 分词器 转换成 拼音词条。

3.3 测试

DSL 语法

{"settings": {"analysis": {"analyzer": {"py_analyzer": {"tokenizer": "ik_max_word","filter": "py"}},"filter": {"py": {"type": "pinyin",// "keep_separate_first_letter": true,"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": "py_analyzer","search_analyzer": "ik_smart"}}}
}

字段说明

  • analysis:定义分析(analysis)部分,这里可以指定自定义的分析器、分词器、过滤器或字符过滤器。

    • py_analyzer:自定义分析器名,
      • ik_max_word:中文分词器,它会尽可能多地切分出词语。
      • filter:“py” 是指在分词后将应用的过滤器名称
    • filter:定义过滤器配置信息
      • py: 自定义过滤器名称,与 py_analyzer 指定的 filter 一致
        • type: 指定过滤器类型为pinyin,即拼音过滤器
        • keep_separate_first_letter: 是否保留每个汉字的首字母,
        • keep_full_pinyin: 是否保留全拼
        • keep_joined_full_pinyin: 是否保留连在一起的完整拼音
        • keep_original:是否保留原始文本
        • limit_first_letter_length:限制首字母长度为N个字符
        • remove_duplicated_term: 是否去除重复的词条
        • none_chinese_pinyin_tokenize:是否对非中文内容不进行拼音分词
  • mappings:映射

    • properties:定义文档字段
      • name:字段名
        • type:字段类型
        • analyzer:在索引时使用 py_analyzer 分析器
        • search_analyzer:在搜索时使用 ik_smart 分析器,它会根据上下文智能地选择分词方式

测试结果

在这里插入图片描述

3.4 analyzer 与 search_analyzer 的区别

在 Elasticsearch 中,analyzer 和 search_analyzer 是用来控制文本如何被分析(即分词和转换)的两个不同阶段的设置。它们的主要区别在于应用的时机和目的。

Analyzer

  • 应用时机:analyzer 设置应用于索引时间。当文档被索引时,字段的内容会通过指定的分析器进行处理,然后将结果存储在倒排索引中。
  • 作用:确保数据以一种结构化的方式存储,使得后续的搜索更加高效和准确。例如,中文文本可能会被分词成单个词语,并可能转换为小写或拼音形式等,以便于检索。

Search Analyzer

  • 应用时机:search_analyzer 设置应用于查询时间。当执行搜索请求时,查询字符串会通过指定的搜索分析器进行处理,以便生成与索引中的词条相匹配的形式。
  • 作用:确保查询字符串按照与索引内容相同的方式进行处理,从而提高搜索的相关性和准确性。它允许你对索引和搜索过程使用不同的分析逻辑,比如可以在索引时采用更细粒度的分词,在搜索时采用更智能的分词方式。

区别总结

  • 索引 vs 搜索:analyzer 用于索引阶段的数据预处理,而 search_analyzer 用于搜索阶段的查询字符串预处理。
  • 灵活性:如果未显式定义 search_analyzer,则默认使用字段的 analyzer。但是,有时为了优化搜索体验,你可能希望在搜索时使用不同于索引时的分析策略,这时就可以单独配置 search_analyzer。

4、自动补全查询

ElasticSearch 提供了 Completion Suggester 查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。

对于文档中字段的类型有一些约束

  • 参与补全查询的字段必须是 completion 类型
  • 字段的内容一般是用来补全的多个词条形成的数组

demo 测试

创建索引库

PUT /test
{"mappings": {"properties": {"title":{"type":"completion"}}}
}

插入测试文档

POST test/_doc
{"title": ["Sony", "WH-1000XM3"]
}POST test/_doc
{"title": ["SK-II", "PITERA"]
}POST test/_doc
{"title": ["Nintendo", "switch"]
}

查询所有文档
在这里插入图片描述
自动补全查询
定义 DSL 语法:

GET test/_search
{"suggest": {						// 使用 Suggest 功能"title_suggest": {				// 自定义 Suggest 名称,可以是任何标识符"text": "s",					// 输入文本 "s",表示自动补全的起始字符串"completion":{				// 使用 Completion Suggestion 类型"field":"title",			// 提供自动补全建议的字段"skip_duplicates":true,		// 跳过重复的建议,避免显示重复内容"size":10					// 限制返回建议的数量为 10}}}
}

测试结果:

在这里插入图片描述

5、酒店搜索测试案例

问题:我们的 hotel 索引库还没有设置拼音分词器,需要修改索引库中的配置信息。但是我们知道索引库是无法修改的,只能删除然后重新创建。

分析

  1. 修改 hotel 索引库结构,设置自定义拼音分词器,添加新字段,用来做自动补全,将 brand、suggestion、city等都放进去,作为自动补全的提示。
  2. 修改索引库的 name、all 字段,使用自定义分词器。
  3. 将 brand、business 添加到 suggestion 字段。
  4. 重新导入数据到索引库

5.1 定义 hotel 索引库

DSL 创建 hotel 索引:

PUT /hotel
{"settings": {"analysis": {"analyzer": {"text_analyzer": {"tokenizer": "ik_max_word","filter": "py"},"completion_analyzer": {"tokenizer": "keyword","filter": "py"}},"filter": {"py": {"type": "pinyin",// "keep_separate_first_letter": true,"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_analyzer","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","copy_to": "all"},"starName": {"type": "keyword"},"business": {"type": "keyword","copy_to": "all"},"location": {"type": "geo_point"},"pic": {"type": "keyword","index": false},"all": {"type": "text","analyzer": "text_analyzer","search_analyzer": "ik_smart"},"suggestion": {"type": "completion","analyzer": "completion_analyzer"}}}
}

5.2 插入 hotel 文档数据

将 brand、city、business 字段内容放入 suggestion 字段中。

public function batchAddDoc()
{$hotels = Hotel::order(['id' => 'asc'])->select();$params = [];foreach ($hotels as $hotel) {$params['body'][] = ['index' => ['_index' => 'hotel','_id'    => $hotel->id,]];# 添加搜索字段$suggestions   = [];$suggestions[] = $hotel->brand;$suggestions[] = $hotel->city;if (strpos($hotel->business, '/') !== false) {$suggestions = array_merge($suggestions, explode('/', $hotel->business));} elseif (strpos($hotel->business, '、') !== false) {$suggestions = array_merge($suggestions, explode('、', $hotel->business));} else {$suggestions[] = $hotel->business;}$params['body'][] = ['id'         => $hotel->id,'name'       => $hotel->name,'address'    => $hotel->address,'price'      => $hotel->price,'score'      => $hotel->score,'brand'      => $hotel->brand,'city'       => $hotel->city,'starName'   => $hotel->star_name,'business'   => $hotel->business,'location'   => $hotel->latitude . ',' . $hotel->longitude,'pic'        => $hotel->pic,'suggestion' => $suggestions];}$result = $this->client->bulk($params);return json($result);
}

5.3 查询 hotel 文档数据

在这里插入图片描述

5.4 自动补全搜索

DSL 语句:

GET hotel/_search
{"suggest": {						        // 使用 Suggest 功能"search_suggest": {				    	// 自定义 Suggest 名称,可以是任何标识符"text": "rj",					      	// 输入文本 "rj",表示自动补全的字符串"completion":{				      	// 使用 Completion Suggestion 类型"field":"suggestion",				// 提供自动补全建议的字段"skip_duplicates":true,				// 跳过重复的建议,避免显示重复内容"size":10				        	// 限制返回建议的数量为 10}}}
}

测试结果:
在这里插入图片描述
PHP 测试示例:

public function search()
{$prefix = 'bj';$result = $this->client->search(['index' => 'hotel','body'  => ['suggest' => ['search_suggest' => ['text' => $prefix,'completion' => ['field' => 'suggestion','skip_duplicates' => true,'size' => 10]]]]]);$options = $result['suggest']['search_suggest'][0]['options'];$data = [];foreach ($options as $option) {$data[] = $option['text'];}return json($data); // 输出:["北京","北京展览馆地区","北京站","北京西站","布吉"]
}

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

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

相关文章

UML 建模实验

文章目录 实验一 用例图一、安装并熟悉软件EnterpriseArchitect16二、用例图建模 实验二 类图、包图、对象图类图第一题第二题 包图对象图第一题第二题 实验三 顺序图、通信图顺序图银行系统学生指纹考勤系统饮料自动销售系统“买到饮料”“饮料已售完”“无法找零”完整版 通信…

Linux环境下 搭建ELk项目 -单机版练习

前言 ELK 项目是一个由三个开源工具组成的日志处理和分析解决方案,ELK 是 Elasticsearch、Logstash 和 Kibana 的首字母缩写。这个项目的目标是帮助用户采集、存储、搜索和可视化大量的日志和事件数据,尤其是在分布式系统中。下面是每个组件的概述&…

day14-16系统服务管理和ntp和防火墙

一、自有服务概述 服务是一些特定的进程,自有服务就是系统开机后就自动运行的一些进程,一旦客户发出请求,这些进程就自动为他们提供服务,windows系统中,把这些自动运行的进程,称为"服务" window…

js进阶语法详解

文章目录 js进阶语法详解一、引言二、闭包与作用域1、闭包1.1、示例代码 2、作用域2.1、示例代码 三、this关键字与函数调用1、this的指向1.1、示例代码 2、apply和call方法2.1、示例代码 四、异步编程1、Promise1.1、示例代码 五、JS的面向对象封装1、封装的概念1.1、构造函数…

Qt WORD/PDF(一)使用 QtPdfium库实现 PDF 预览

文章目录 一、简介二、下载 QtPdfium三、加载 QtPdfium 动态库四、Demo 使用 关于QT Widget 其它文章请点击这里: QT Widget 国际站点 GitHub: https://github.com/chenchuhan 国内站点 Gitee : https://gitee.com/chuck_chee 姊妹篇: Qt WORD/PDF&#x…

.Net WebAPI(一)

文章目录 项目地址一、WebAPI基础1. 项目初始化1.1 创建简单的API1.1.1 get请求1.1.2 post请求1.1.3 put请求1.1.4 Delete请求 1.2 webapi的流程 2.Controllers2.1 创建一个shirts的Controller 3. Routing3.1 使用和创建MapControllers3.2 使用Routing的模板语言 4. Mould Bind…

Java操作Redis-Jedis

介绍 前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在 java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使 用JDBC操作MySQL数据库一样。 Redis 的 Java 客户端很多&#xff0…

Vue3 + Element-Plus + vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS 父组件实现真正上传(最新保姆级)

Vue3 Element-Plus vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS(最新保姆级)父组件实现真正上传 1、效果展示2、UploadImage.vue 组件封装3、相关请求封装4、SwiperConfig.vue 调用组件5、后端接口 1、效果展示 如果没有安装插件&…

将 Ubuntu 22.04 LTS 升级到 24.04 LTS

Ubuntu 24.04 LTS 将支持 Ubuntu 桌面、Ubuntu 服务器和 Ubuntu Core 5 年,直到 2029 年 4 月。 本文将介绍如何将当前 Ubuntu 22.04 系统升级到最新 Ubuntu 24.04 LTS版本。 备份个人数据 以防万一,把系统中的重要数据自己备份一下~ 安装配置SSH访问…

宝塔SSL证书申请失败,报错:申请SSL证书错误 module ‘OpenSSL.crypto‘ has no attribute ‘sign‘(已解决)

刚安装宝塔申请SSL就报错:申请SSL证书错误 module OpenSSL.crypto has no attribute sign 面板、插件版本:9.2.0 系统版本:Alibaba Cloud Linux 3.2104 LTS 问题:申请SSL证书错误 module OpenSSL.crypto has no attribute sign…

<mutex>注释 12:重新思考与猜测、补充锁的睡眠与唤醒机制,结合 linux0.11 操作系统代码的辅助(下)

(60)继续分析,为什么 timed_mutex 可以拥有准时的等待时间: 逐步测试: 以及: 以及: 以及: 上面的例子里之所以这么编写。无论 timed_mutex 里的定时等待函数,还是 条件…

【MySQL】InnoDB引擎中的Compact行格式

目录 1、背景2、数据示例3、Compact解释【1】组成【2】头部信息【3】隐藏列【4】数据列 4、总结 1、背景 mysql中数据存储是存储引擎干的事,InnoDB存储引擎以页为单位存储数据,每个页的大小为16KB,平时我们操作数据库都是以行为单位进行增删…

Kylin麒麟操作系统 | 网络链路聚合配置(team和bond)

目录 一、理论储备1. 链路聚合 二、任务实施1. team模式2. bond模式 一、理论储备 1. 链路聚合 链路聚合是指将多个物理端口捆绑在一起,形成一个逻辑端口,以实现出/入流量在各成员端口中的负载分担。链路聚合在增加链路带宽、实现链路传输弹性和冗余等…

Linux中用户和用户管理详解

文章目录 Linux中用户和用户管理详解一、引言二、用户和用户组的基本概念1、用户账户文件2、用户组管理 三、用户管理操作1、添加用户2、设置用户密码3、删除用户 四、用户组操作1、创建用户组2、将用户添加到用户组 五、总结 Linux中用户和用户管理详解 一、引言 在Linux系统…

多进程并发跑程序:pytest-xdist记录

多进程并发跑程序:pytest-xdist记录 pytest -s E:\testXdist\test_dandu.py pytest -s testXdist\test_dandu.py pytest -s :是按用例顺序依次跑用例 pytest -vs -n auto E:\testXdist\test_dandu.py pytest -vs -n auto,auto表示以全部进程…

笔记--(Shell脚本04)、循环语句与函数

循环语句 1、for语句的结构 for 变量名 in 取值列表 do 命令序列 done for 收件人 in 邮件地址列表 do 发送邮件 done for i in {1..10} doecho $i done[rootlocalhost shell]# ./ce7.sh 1 2 ...... 9 101 #!/bin/bash2 3 for i in seq 1 104 do5 echo $i6 done[rootlocal…

用.Net Core框架创建一个Web API接口服务器

我们选择一个Web Api类型的项目创建一个解决方案为解决方案取一个名称我们这里选择的是。Net 8.0框架 注意,需要勾选的项。 我们找到appsetting.json配置文件 appsettings.json配置文件内容如下 {"Logging": {"LogLevel": {"Default&quo…

go引用包生成不了vendor的问题

比如我要引入github.com/jinzhu/gorm这个包. 1. 首先获取包 go get github.com/jinzhu/gorm 这时go.mod文件中也有这个包依赖信息了. 2. 然后构建vendor go mod vendor 结果发现vendor目录下没有生成对应的包, 而且modules.txt也注释掉这个包了. 原因是没有其进行引用, go…

36. Three.js案例-创建带光照和阴影的球体与平面

36. Three.js案例-创建带光照和阴影的球体与平面 实现效果 知识点 Three.js基础 WebGLRenderer WebGLRenderer 是Three.js中最常用的渲染器,用于将场景渲染到网页上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobject可选参数&#…

el-table表格嵌套子表格:展开所有内容;对当前展开行内容修改,当前行默认展开;

原文1 原文2 原文3 一、如果全部展开 default-expand-all"true" 二、设置有数据的行打开下拉 1、父table需要绑定两个属性expand-row-key和row-key <el-table:data"tableData":expand-row-keys"expends" //expends是数组&#xff0c;设置…