需求

雪花啤酒  需要搜索雪花、啤酒 、雪花啤酒、xh、pj、xh啤酒、雪花pj

ik导入

参考https://www.cnblogs.com/LQBlog/p/10443862.html,不需要修改源码步骤就行

拼音分词器导入

跟ik一样 下载下来打包移动到es plugins 目录名字改为pinyin https://github.com/medcl/elasticsearch-analysis-pinyin

测试

get请求:http://127.0.0.1:9200/_analyze

body:

{
"analyzer":"pinyin",
"text":"雪花啤酒"
}

响应:

{
"tokens": [
{
"token": "xue",
"start_offset": 0,
"end_offset": 0,
"type": "word",
"position": 0
},
{
"token": "xhpj",
"start_offset": 0,
"end_offset": 0,
"type": "word",
"position": 0
},
{
"token": "hua",
"start_offset": 0,
"end_offset": 0,
"type": "word",
"position": 1
},
{
"token": "pi",
"start_offset": 0,
"end_offset": 0,
"type": "word",
"position": 2
},
{
"token": "jiu",
"start_offset": 0,
"end_offset": 0,
"type": "word",
"position": 3
}
]
}

说明导入成功

测试中文加拼音搜索

自定义mapping和自定义分词器

put请求:http://127.0.0.1:9200/opcm3

body:

{
"settings": {
"analysis": {
"analyzer": {
"ik_pinyin_analyzer": {//自定义一个分词器名字叫ik_pinyin_analyzer
"type": "custom",//表示自定义分词器
"tokenizer": "ik_smart",//使用ik分词 ik_smart为粗粒度分词 ik_max_word为最细粒度分词
"filter": ["my_pinyin"]//分词后结果 交给过滤器再次分词
},
"onlyOne_analyzer": {
"tokenizer": "onlyOne_pinyin"
}
},
"tokenizer": {
"onlyOne_pinyin": {
"type": "pinyin",
"keep_separate_first_letter": "true",
"keep_full_pinyin":"false"
}
},"filter": {
"my_pinyin": {//定义过滤器
"type": "pinyin",
"keep_joined_full_pinyin": true,//分词的时候词组首字母分词后组合 如:雪花 分词:xuehua xh
"keep_separate_first_letter": true//分词的时候支持首字母不单独分词如:会分词xue hua xuehua xh x,h
"none_chinese_pinyin_tokenize": true//xh 分词为x,h,xh }
}
} },
"mappings": {
"doc": {
"properties": {
"productName": {
"type": "text",
"analyzer": "ik_pinyin_analyzer",//指定分词索引为自定义分词 中文分词后再通过filter交给pinyin分词
"fields": {//暂时未用 只是保留让 自己能够知道有这种方式根据不同条件选择不同的搜索分词
"keyword_once_pinyin": {//新的分词字段 只分词不存在source productName.keyword_once_pinyin 查询时需要判断如果是单字母使用此搜索
"type": "text",
"analyzer": "onlyOne_analyzer"
}
}
}
} } }
}

filter个人理解

我的理解是   ik分词 然后将分词后的逐项结果通过filter交给拼音分词  雪花啤酒 ik会分成 雪花,啤酒    然后雪花交给pinyin会分词 xue,hua,xh,x,h  啤酒会分词 pi,jiu,p,j

插入测试数据

http://127.0.0.1:9200/opcm3/doc/1

{
"productName":"雪花纯生勇闯天涯9度100ml"
}

put请求:http://127.0.0.1:9200/opcm3/doc/2

body:

{
"productName":"金威纯生勇闯天涯9度100ml"
}

查看分词结果

get请求:http://127.0.0.1:9200/opcm3/topic/{id}/_termvectors?fields=productName

get请求:http://127.0.0.1:9200/opcm3/topic/{id}/_termvectors?fields=productName.keyword_once_pinyin

测试搜索

http://127.0.0.1:9200/opcm3/_search

{
"query":{
"match_phrase":{
"productName":{
"query":"雪花纯生"
}
}
}
}

会查出雪花纯生和金威纯生 看个人是模糊匹配还是相邻匹配 选用match或者match_phrase

我的需求是相邻匹配改为

{
"query":{
"match_phrase":{
"productName":{
"query":"雪花纯生"
}
}
}
}

则只会搜索出雪花纯生

搜索雪花纯生9度的产品

{
"query":{
"match_phrase":{
"productName":{
"query":"雪花纯生9度"
}
}
}
}

会发现搜索不出来数据

原因请查阅:https://www.cnblogs.com/LQBlog/p/10580247.html

改为就能搜索出来:

{
"query":{
"match_phrase":{
"productName":{
"query":"雪花纯生9度",
"slop":5
}
}
}
}

pingpin分词还支持很多参数 比如:

以上模型排查及解决

添加测试数据

{
"productName":"纯生"
}

{
"productName":"纯爽"
}

测试

搜索

{
"query":{
"match_phrase":{
"productName":{
"query":"纯生",
"slop":5
}
}
}
}

返回结果

{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 2.8277423,
"hits": [
{
"_index": "opcm3",
"_type": "doc",
"_id": "1",
"_score": 2.8277423,
"_source": {
"productName": "纯爽"
}
},
{
"_index": "opcm3",
"_type": "doc",
"_id": "2",
"_score": 1.4466299,
"_source": {
"productName": "纯生"
}
}
]
}
}

可以发现纯爽也出来了

排查

1.查看纯爽分词结果

http://127.0.0.1:9200/opcm3/doc/2/_termvectors?fields=productName

[c,chun,s,sheng]

[c,chun,s,shuang]

2.查看搜索分词

http://127.0.0.1:9200/opcm3/_validate/query?explain
{
"query":{
"match_phrase":{
"productName":{
"query":"纯生",
"slop":5
}
}
}
}

body

{
"valid": true,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"explanations": [
{
"index": "opcm3",
"valid": true,
"explanation": "productName:\"(c chun) (s sheng)\"~5"
}
]
}

可以理解为index=(c or chun) and (s or shuang)

所以c,s 匹配了纯爽

解决办法

分词按最小粒度分 搜索 按最大粒度分

如纯生文档分词为[chun,sheng,chun,sheng,cs,c,s]

搜索分词为[chun,sheng,chunsheng]

一下模型就能满足搜索: 雪花,雪花cs ,雪花chunsheng ,xhcs,xh纯生,雪花纯生 都能正确搜索出数据

{
"settings": {
"analysis": {
"analyzer": {
"ik_pinyin_analyzer": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": ["pinyin_max_word_filter"]
},
"ik_pingying_smark": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": ["pinyin_smark_word_filter"] }
},
"filter": {
"pinyin_max_word_filter": {
"type": "pinyin",
"keep_full_pinyin": "true",#分词全拼如雪花 分词xue,hua
"keep_separate_first_letter":"true",#分词简写如雪花 分词xh
"keep_joined_full_pinyin":true#分词会quanpin 连接 比如雪花分词 xuehua
},
"pinyin_smark_word_filter": {
"type": "pinyin",
"keep_separate_first_letter": "false",#不分词简写如雪花 分词不分词xh
"keep_first_letter":"false"#不分词单个首字母 如雪花 不分词 x,h
}
}
} },
"mappings": {
"doc": {
"properties": {
"productName": {
"type": "text",
"analyzer": "ik_pinyin_analyzer",#做文档所用的分词器
"search_analyzer":"ik_pingying_smark"#搜索使用的分词器
}
} } }
}

解决办法2

elasticsearch实战 中文+拼音搜索的更多相关文章

  1. elasticsearch之拼音搜索

    拼音搜索在中文搜索环境中是经常使用的一种功能,用户只需要输入关键词的拼音全拼或者拼音首字母,搜索引擎就可以搜索出相关结果.在国内,中文输入法基本上都是基于汉语拼音的,这种在符合用户输入习惯的条件下缩短 ...

  2. ElasticSearch 中文分词搜索环境搭建

    ElasticSearch 是强大的搜索工具,并且是ELK套件的重要组成部分 好记性不如乱笔头,这次是在windows环境下搭建es中文分词搜索测试环境,步骤如下 1.安装jdk1.8,配置好环境变量 ...

  3. Elasticsearch实现类似 like '?%' 搜索

    在做搜索的时候,下拉联想词的搜索肯定是最常见的一个场景,用户在输入的时候,要自动补全词干,说得简单点,就是以...开头搜索,如果是数据库,一句SQL就很容易实现,但在elasticsearch如何实现 ...

  4. I-team 博客全文检索 Elasticsearch 实战

    一直觉得博客缺点东西,最近还是发现了,当博客慢慢多起来的时候想要找一篇之前写的博客很是麻烦,于是作为后端开发的楼主觉得自己动手丰衣足食,也就有了这次博客全文检索功能Elasticsearch实战,这里 ...

  5. Elasticsearch实战总结

    上手elasticsearch有段时间了,主要以应用为主,未做深入的研究,下面就简单的日常作个简单的总结,做个记录. 版本问题 es版本繁杂,让首次使用的人无从下手.常见的有2+.5+版本,最新版已达 ...

  6. 【Solr】 solr对拼音搜索和拼音首字母搜索的支持

    问:对于拼音和拼音首字母的支持,当你在搜商品的时候,如果想输入拼音和拼音首字母就给出商品的信息,怎么办呢? 实现方式有2种,但是他们其实是对应的.  用lucene实现 1.建索引, 多建一个索引字段 ...

  7. 为Elasticsearch添加中文分词,对比分词器效果

    http://keenwon.com/1404.html Elasticsearch中,内置了很多分词器(analyzers),例如standard (标准分词器).english(英文分词)和chi ...

  8. ElasticSearch实战-日志监控平台

    1.概述 在项目业务倍增的情况下,查询效率受到影响,这里我们经过讨论,引进了分布式搜索套件——ElasticSearch,通过分布式搜索来解决当下业务上存在的问题.下面给大家列出今天分析的目录: El ...

  9. Elasticsearch java api 基本搜索部分详解

    文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...

随机推荐

  1. ArraySegment

    第一个构造函数 Initializes a new instance of the ArraySegment<T> structure that delimits all the elem ...

  2. Nearest-Neighbor Methods(ESL读书笔记)

    Nearest-neighbor methods use those observations in the training set T closest in input space to x  f ...

  3. PCB 无需解压,直接读取Zip压缩包指定文件 实现方法

    最近有一项需求,将电测试点数后台批量写入到工程系统流程指示中,而电测试文件存在压缩包中,压缩包存在公共网络盘 示例图: 一.采用原始方法(4步完成): 第1步:.网络盘ZIP拷到本地, 第2步:解压Z ...

  4. yii 面包屑

    Yii的Breadcrumbs 是Yii的路径插件,使用方法: <?php $this->widget('zii.widgets.CBreadcrumbs', array('links'= ...

  5. SQL Server中char与varchar数据类型区别

    在SQL Server中char类型的长度是不可变的,而varchar的长度是可变的 . 存入数据时: 如果数据类型为char时,当定义一个字段固定长度时,如果存进去数据长度小于char的长度,那么存 ...

  6. max-age 和 Expires

    网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private.no-cache.max-age.must-revalidate等,默认为private.   Ex ...

  7. C++版的LLC代码

    图像稀疏编码总结:LLC和SCSPM,文章对稀疏编码讲解非常详细. <Locality-constrained Linear Coding for Image Classification> ...

  8. Quartz+Topshelf 作业

    小记: 引用Quartz.Topshelf.Topshelf.Quartz 使用方法: http://www.cnblogs.com/mushroom/p/4952461.html http://ww ...

  9. Oracle中REGEXP_SUBSTR函数

    Oracle中REGEXP_SUBSTR函数 Oracle中REGEXP_SUBSTR函数的使用说明: 题目如下: 在oracle中,使用一条语句实现将'17,20,23'拆分成'17','20',' ...

  10. promise原理及使用方法

    Promise 的含义 所谓Promise ,简单说就是一个容器,里面保存着某个未来才回结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息. re ...