Elasticsearch 自定义分成器 拼音搜索 搜索自动补全 Java对接

介绍

通常用于将文档中的文本数据拆分成易于索引的词项(tokens)。有时,默认的分词器无法满足特定应用需求,这时就可以创建 自定义分词器 来实现定制化的文本分析。

自定义分词器组成

  • Char Filters(字符过滤器):
    字符过滤器在文本被传给分词器之前,先对字符进行预处理。常见的处理包括去除特殊字符、替换字符、转换字符等。
    例如:html_strip 字符过滤器可以去除 HTML 标签,mapping 字符过滤器可以将某些字符映射为其他字符。

  • Tokenizer(分词器):
    将输入的文本拆分成一个个词项(tokens)。
    常见的分词器有 standard、keyword、pattern、whitespace 等,也可以自定义一个分词器来根据特定规则进行分割。

  • Token Filters(词项过滤器):
    词项过滤器用于对分词后的词项进行进一步的处理,如小写化、去除停用词、词干提取等。
    例如,lowercase 过滤器将所有词项转为小写,stop 过滤器会去除常见的无意义词(如 “a”, “the” 等)。

注意事项

  • 倒排索引:在构建倒排索引时,拼音分词器可以将每个词语转化为拼音,并为每个拼音索引相关的文档。这种方法依赖于拼音本身,因此在创建索引时,拼音是一个便于检索和存储的统一标准。然而,这种方法并不考虑具体的字或词的实际含义。
  • 搜索时的查询:在搜索过程中,用户通常会直接输入汉字(而不是拼音),而且搜索时往往依赖的是汉字的实际语义。如果使用拼音进行搜索,可能会出现同音字或多音字的歧义,导致用户查询无法准确匹配目标内容。例如,拼音 “mā” 可以代表“妈”、“马”或“麻”,但用户搜索的汉字可能是“马”而不是“妈”,此时拼音搜索就会产生误差。

这时候搜索和创建应该使用不同的分词器。所以就需要使用自定义分词器。自定义分词器在创建索引库的时候就应该创建。

创建自定义分词器的索引库

PUT http://172.23.4.130:9200/goods

{
  "settings": {
    "analysis": {
      "analyzer": {
        "mx_analyzer": {  // 定义自定义分析器名称为 mx_analyzer
          "tokenizer": "ik_max_word",  // 使用 "ik_max_word" 分词器,进行中文最大化分词
          "filter": "py"  // 使用拼音过滤器 "py" 进行拼音转换
        }
      },
      "filter": {
        "py": {  // 配置拼音过滤器
          "type": "pinyin",  // 设置为拼音类型的过滤器
          "keep_full_pinyin": false,  // 不保留完整拼音(仅保留简拼)
          "keep_joined_full_pinyin": true,  // 保留拼音连在一起(例如“北京”变为“bj”)
          "keep_original": true,  // 保留原始中文词汇
          "limit_first_letter_length": 16,  // 限制拼音首字母的长度为16
          "remove_duplicated_term": true,  // 删除重复的拼音词项
          "none_chinese_pinyin_tokenize": false  // 不进行非中文拼音的分词处理
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {  // title字段配置
        "type": "text",  // 使用 "text" 类型,适合进行分词的文本字段
        "analyzer": "mx_analyzer",  // 使用自定义的 mx_analyzer 分析器进行分词
        "search_analyzer": "ik_smart"  // 搜索时使用 "ik_smart" 分析器进行分析(简化分词)
      },
      "transport": {  // transport字段配置
        "type": "double"  // 使用 "double" 类型,用于数值数据(浮动小数)
      }
    }
  }
}

拼音分词库文档:https://github.com/medcl/elasticsearch-analysis-pinyin

添加测试数据

POST http://172.23.4.130:9200/goods/_doc/n

{
     "title": "广东梅州盐焗鸡中翅客家特产盐局鸡翅中网红零食小吃熟食"
}

测试搜索

GET http://172.23.4.130:9200/goods/_search
不管使用中文还是英文 全拼还是简写 都可以正常搜索出该商品

{
    "query":{
        "match":{
            "title":"yjj"
        }
    }
}

在这里插入图片描述

搜索的自动补全

Elasticsearch 提供了Completion suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询的效率,对于文档中字段的类型有一些约束。

  • 参与补全查询的字段必须是completion类型
  • 字段的内容一般是用来补全的多个词条形成的数组,也就是提示词语
{
  "settings": {
    "analysis": {
        "analyzer":{
            "mx_analyzer":{
                "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":{
                "title": {
                    "type": "text",
                    "analyzer": "mx_analyzer",
                    "search_analyzer":"ik_smart"
                },
                "suggestion":{ //搜索的自动补全
                  "type":"completion",
                  "analyzer":"completion_analyzer"
                }
    }
  }
}

创建搜索关键字
PUT http://172.23.4.130:9200/goods/_doc/1

{
     "title": "客家散养土猪原味腊肠香肠广东梅州特产咸香",
     "suggestion":["土猪","腊肠","香肠","散养"] 
}

自动补全查询
GET http://172.23.4.130:9200/goods/_search

{
  "suggest": {
    "title_suggest": {  // title_suggest 自定义名称
      "text": "l",  // 搜索的文本
      "completion": {  // 使用"completion" 进行自动补全
        "field": "suggestion",  // 指定用于自动补全的字段名
        "skip_duplicates": true,  // 跳过重复的建议
        "size": 15  // 返回的最大数量
      }
    }
  }
}

对应Java代码

SearchRequest request =new SearchRequest(GOODS_INDEX);
request.source().suggest(new SuggestBuilder().addSuggestion("title_suggest",
        SuggestBuilders.completionSuggestion("suggestion").prefix(text)
                .skipDuplicates(true).size(15)));

依赖

版本7.12.1

   <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
    </dependency>

配置文件

application.yaml

es:
  ip: 172.23.4.130
  port: 9200
  user: elastic
  password: qwertyuiop

配置类

@Component
@ConfigurationProperties(prefix = "es")
@Data
public class ElasticsearchProperties {
    private String ip;
    private int port;
    private String user;
    private String password;

}

配置连接

@Configuration
@RequiredArgsConstructor
public class ElasticsearchConfig {

    private final ElasticsearchProperties elasticsearchProperties;

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        // 配置基本认证
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                new AuthScope(elasticsearchProperties.getIp(), elasticsearchProperties.getPort()),
                new UsernamePasswordCredentials(elasticsearchProperties.getUser(), elasticsearchProperties.getPassword())
        );

        RestClientBuilder builder = RestClient.builder(new HttpHost(elasticsearchProperties.getIp(), elasticsearchProperties.getPort(), "http"));
        builder.setHttpClientConfigCallback(httpClientBuilder -> {
            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        });
        // 创建并返回 RestHighLevelClient 实例
        return new RestHighLevelClient(builder);
    }
}

JSON格式化

将JSON转成实体类

public class EsUtils {
    public static <T>List<T>  toList(SearchHit[] hits, Class<T> clazz) {
        List<T> retList = new ArrayList<>();
        for (SearchHit item : hits) {
            String json = item.getSourceAsString();  // 获取 JSON 字符串
            T obj = JSONUtil.toBean(json, clazz);    // 使用 Hutool 将 JSON 转换为对象
            retList.add(obj);
        }
        return retList;  // 返回结果列表
    }
}

搜索自动补全API

/**
 * 商品搜索框的自动补全
 * @param text
 * @return
 */
@Override
@SneakyThrows
public List<String> suggestion(String text) {
    String Custom_Name ="title_suggest";
    List<String> list =new ArrayList<>();
    SearchRequest request =new SearchRequest(GOODS_INDEX);
    request.source().suggest(new SuggestBuilder().addSuggestion(Custom_Name,
            SuggestBuilders.completionSuggestion("suggestion").prefix(text)
                    .skipDuplicates(true).size(15)));
    SearchResponse response= client.search(request,RequestOptions.DEFAULT);
    Suggest suggest =response.getSuggest();
    CompletionSuggestion suggestion =suggest.getSuggestion(Custom_Name);
    List<CompletionSuggestion.Entry.Option> options =suggestion.getOptions();
    for (CompletionSuggestion.Entry.Option option :options){
        list.add(option.getText().toString());
    }
    return list;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leecode刷题C语言之完成所有交易的初始最少钱数

执行结果:通过 执行用时和内存消耗如下&#xff1a; long long minimumMoney(int** transactions, int transactionsSize,int* transactionsColSize) {long long total_lose 0;int res 0;for (int i 0; i < transactionsSize; i) {int cost transactions[i][0];int cas…

案例研究丨浪潮云洲通过DataEase推进多维度数据可视化建设

浪潮云洲工业互联网有限公司&#xff08;以下简称为“浪潮云洲”&#xff09;成立于2018年&#xff0c;定位于工业数字基础设施建设商、具有国际影响力的工业互联网平台运营商、生产性互联网头部服务商。截至目前&#xff0c;浪潮云洲工业互联网平台连续五年入选跨行业跨领域工…

C++——动态管理

目录 一、C/C内存分布二、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free三、C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 四、operator new与operator delete函数4.1 operator new与operator delete函数 五、new和delete的实现原…

three.js+WebGL踩坑经验合集(4.1):THREE.Line2的射线检测问题(注意本篇说的是Line2,同样也不是阈值方面的问题)

上篇大家消化得如何了&#xff1f; 笔者说过&#xff0c;1级编号不同的两篇博文相对独立&#xff0c;所以这里笔者还是先给出完整代码&#xff0c;哪怕跟&#xff08;3&#xff09;没有太大区别。 这里我们把线的粗细调成5&#xff08;排除难选中的因素&#xff09;&#xff…

Vue2下篇

插槽&#xff1a; 基本插槽&#xff1a; 普通插槽&#xff1a;父组件向子组件传递静态内容。基本插槽只能有一个slot标签&#xff0c;因为这个是默认的位置&#xff0c;所以只能有一个 <!-- ParentComponent.vue --> <template> <ChildComponent> <p>…

【Unity3D】aab包太大无法上传Google问题

目录 一、勾选Split Application Binary&#xff0c;Unity直接打aab包 勾选Split Application Binary选项的影响 不勾选Split Application Binary选项的影响 总结 2、导出Android工程打包aab 一、勾选Split Application Binary&#xff0c;Unity直接打aab包 超出150MB部分…

第6章 数据结构—列表与列表项讲解--总结

整理 野火 《FreeRTOS 内核实现与应用开发实战指南》—基于野火 STM32 全系列&#xff08;M3/4/7&#xff09;开发板 文章目录 第6章 数据结构—列表与列表项讲解--总结6.1 C 语言链表简介6.1.1 单向链表6.1.2 双向链表6.1.3 链表与数组的对比 6.2 FreeRTOS 中链表的实现6.2.1 …

强化学习-Deep Q Network

文章目录 Deep Q Networkzip(*batch)的内部实现假设&#xff1a;结果&#xff1a; Deep Q Network 这种方式很适合格子游戏。因为格子游戏中的每一个格子就是一个状态&#xff0c;这是离散的&#xff0c;但在现实生活中&#xff0c;很多状态并不是离散而是连续的。所以我们可以…

C语言-构造数据类型

1、构造数据类型 结构体、共用体、枚举。 2、结构体 1、结构体的定义 结构体是一个自定义的复合数据类型&#xff0c;它允许将不同类型的数据组合在一起。 struct 结构体名 {数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;数据类型4 成员变量4; } 2、结构体变…

FPGA实现任意角度视频旋转(二)视频90度/270度无裁剪旋转

本文主要介绍如何基于FPGA实现视频的90度/270度无裁剪旋转&#xff0c;旋转效果示意图如下&#xff1a; 为了实时对比旋转效果&#xff0c;采用分屏显示进行处理&#xff0c;左边代表旋转前的视频在屏幕中的位置&#xff0c;右边代表旋转后的视频在屏幕中的位置。 分屏显示的…

Spark/Kafka

文章目录 项目地址一、Spark1. RDD1.1 五大核心属性1.2 执行原理1.3 四种创建方式二、Kafka2.1 生产者(1)分区器(2)生产者提高吞吐量(3) 生产者数据可靠性数据传递语义幂等性和事务数据有序2.2 Broker(1)Broker工作流程(2)节点服役和退役2.3 副本(1)Follower故障细…

win32汇编环境,函数的编写与调用、传值或返回值等

;运行效果 ;win32汇编环境,函数的编写与调用、传值或返回值等 ;函数在被调用的时候&#xff0c;如果此函数实体在前面&#xff0c;可以不用声明。如果实体在后面&#xff0c;则需要先声明。类似于下面的DlgProc函数&#xff0c;因为它的实体在后面&#xff0c;所以需要在调用之…

[Spring] Gateway详解

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

回顾2024,展望2025

项目 LMD performance phase2 今年修修补补&#xff0c;设计和做了很多item&#xff0c;有时候自己都数不清做了什么大大小小的item&#xff0c;但是for LMD performance phase2的go-live确实是最大也是最难的了&#xff0c;无论什么系统&#xff0c;只要用的人多了&#xff…

旅游风景的代码项目

敦煌莫高窟&#xff1a;用代码打开千年艺术的大门 ——一个零基础也能看懂的神奇项目 前言&#xff1a;当古老艺术遇上现代代码 想象一下&#xff0c;你坐在电脑前&#xff0c;指尖轻轻一点&#xff0c;就能穿越到敦煌莫高窟——看飞天的衣袂飘飘、听千年的驼铃声声。这不是科…

解决lombok注解失效

问题描述 当出现使用lombok的注解, 但是找不到符号, 或者使用Getter注解却获取不到属性值 就像下面这样 原因: 新版本lombok自动引入了一个插件, 将下面这串代码删除后, 刷新并清除缓存即可解决

leetcode hot 100 搜索二维矩阵II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,2…

CentOS7安装使用containerd

一&#xff0c;安装 1.1、安装containerd 下载 https://github.com/containerd/containerd/releases/download/v1.7.24/cri-containerd-cni-1.7.24-linux-amd64.tar.gz wget https://github.com/containerd/containerd/releases/download/v1.7.24/cri-containerd-cni-1.7.24-…

easyexcel读取写入excel easyexceldemo

1.新建springboot项目 2.添加pom依赖 <name>excel</name> <description>excelspringboot例子</description><parent> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId&…

2025数学建模美赛|F题成品论文

国家安全政策与网络安全 摘要 随着互联网技术的迅猛发展&#xff0c;网络犯罪问题已成为全球网络安全中的重要研究课题&#xff0c;且网络犯罪的形式和影响日益复杂和严重。本文针对网络犯罪中的问题&#xff0c;基于多元回归分析和差异中的差异&#xff08;DiD&#xff09;思…