当前位置: 首页 > news >正文

外贸型网站制作/品牌整合营销传播

外贸型网站制作,品牌整合营销传播,微信网站作用,新浪网今日乌鲁木齐新闻2019独角兽企业重金招聘Python工程师标准>>> 最近在工作中用到拼音搜索,目前参考靠网上的例子做出一套,在这跟大家分享一下。 这套代码可以识别包快拼音缩写在内的拼音与汉字混合的字符串(例如:xiug手机h --> 修改手…

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

最近在工作中用到拼音搜索,目前参考靠网上的例子做出一套,在这跟大家分享一下。

这套代码可以识别包快拼音缩写在内的拼音与汉字混合的字符串(例如:xiug手机h --> 修改手机号)

话不多说,直接开始:

1. 首先有一张中文词语对应拼音的表,然后建一张词语点击量的表(用于记录词语的常用度)

PinyinWord table

CREATE TABLE "public"."pinyinword" ("id" text COLLATE "default" NOT NULL,"word" text COLLATE "default" NOT NULL,"whole" text COLLATE "default" NOT NULL,"acronym" text COLLATE "default" NOT NULL,"wordlength" int4 NOT NULL,"wholelength" int4 NOT NULL,"acronymlength" int4 NOT NULL
)

WordClick table

CREATE TABLE "public"."wordclick" ("wordcontent" text COLLATE "default","id" text COLLATE "default" NOT NULL
)

表中数据自行初始化

2. 接下来介绍两个数据类型,在分析input时起到很重要的作用

  • /**
    * 词元
    */
    public class Lexeme {private String content; //词元内容private LexemeType lexemeType; //词元类型
    }public enum LexemeType {CHINESE, //中文WHOLE, //全拼ACRONYM //拼音首字母缩写
    }
    /**
    * 中文句子(处理用户输入的类)
    */
    public class ChineseSentence {private String content; // 用户输入内容private List<Lexeme> sentenceUnits; // content中包含的词元private SentenceType sentenceType; // 句子最低级类型(不能set,赋值请看initSentenceType())public String getContent() {return content;}public void setContent(String content) {this.content = content;}public List<Lexeme> getSentenceUnits() {return sentenceUnits;}public SentenceType getSentenceType() {return sentenceType;}public void setSentenceUnits(List<Lexeme> sentenceUnits) {this.sentenceUnits = sentenceUnits;initSentenceType();}private void initSentenceType() {sentenceType = SentenceType.CHINESE_SENTENCE;for (Lexeme lexeme : sentenceUnits) {if (lexeme.getLexemeType() == LexemeType.ACRONYM) {sentenceType = SentenceType.ACRONYM_SENTENCE;break;} else if (lexeme.getLexemeType() == LexemeType.WHOLE&& sentenceType == SentenceType.CHINESE_SENTENCE) {sentenceType = SentenceType.WHOLE_SENTENCE;}}}
    }

     

3. 接下来就是处理用户输入(xiug手机h),使用正则表达式将目标分解成词元(Lexeme)并 生成句子

//正则表达式(从网上copy下来做了一些修改,识别中文和疑似的拼音)
private static final String SUSPECTED_PINYIN_REGEX  = "[\\u4e00-\\u9fa5]|(sh|ch|zh|[^aoeiuv])?[iuv]?(ai|ei|ao|ou|er|ang?|eng?|ong|a|o|e|i|u|ng|n)?";

使用这个正则表达式可能会截取出 不存在的拼音组合,比如说jvao

这种直接成 j,v,a,o(找一个拼音组合的库,看看截出来的拼音属不属于库里即可)

经过截取并给每个词元附一个lexemeType,得到下边的结果

091637_TtXX_3001485.png

4. 接下来就是对句子中词元逐个进行分析

首先简要说明一下分析原理

先看一下查询条件

140659_JwAI_3001485.png

解释一下查询参数,首先是lexemeType 这个字段是指定搜索的词级,必须按照句子的最低词级进行搜索

例如: '修改'  --> LexemeType.CHINESE

              'xiu改'  --> LexemeType.WHOLE

              '修g'  --> LexemeType.ACRONYM

Search结尾的三个参数是用来做搜索的,他们在SQL中用来做like操作, 这样可以击中索引

and pinyinword.acronym like #{acronymSearch} || '%'

由于用户输入的句子中可能含有中文或者拼音,这两种类型里需要进行过滤

比如说用户输入  ‘修g’  我们用最低词级进行搜索  就是  like 'xg' %  这样可能搜到  '鞋柜'  所以我用了chineseFilter 和 pinyinFilter 来进行过滤(把 '%修%' append到chineseFilter中),这样查询条件就变成了  

and pinyinword.acronym like #{acronymSearch} || '%'
and pinyinword.word like #{chineseFilter}

这样就不会搜到 '鞋柜' 了

来看一下mybatis下的SQL,这里join了wordclick表,取得了每个词语的点击量,用来排序

<select id="searchByClickCount" resultType="model.value.WordClickCount" parameterType="model.options.PinyinWordAnalyzeSearchOptions">selectpw.word word, count(wc.id) clickCountfromPinyinWord pw left join wordclick wc on wc.wordcontent = pw.wordwhere 1=1<choose><when test="lexemeType.equals('CHINESE')"><if test="chineseSearch!=null">and pw.word like #{chineseSearch} || '%'</if>group by pw.wordorder by clickCount desc<if test="paging">limit 5 offset 0</if></when><when test="lexemeType.equals('WHOLE')"><if test="wholeSearch!=null">and pw.whole like #{wholeSearch} || '%'</if><if test="chineseFilter!=null">and pw.word like #{chineseFilter}</if>group by pw.wordorder by clickCount desc<if test="paging">limit 5 offset 0</if></when><otherwise><if test="acronymSearch!=null">and pw.acronym like #{acronymSearch} || '%'</if><if test="chineseFilter!=null">and pw.word like #{chineseFilter}</if><if test="pinyinFilter!=null">and pw.whole like #{pinyinFilter}</if>group by pw.wordorder by clickCount desc<if test="paging">limit 5 offset 0</if></otherwise></choose></select>

然后是分析用户的输入,把查询条件生成出来

这是部分代码,足以明了 查询条件生成原则了

        LexemeType currentLexemeType; //当前词元类型LexemeType lastLexemeType = null; //之前词元最低级List<Lexeme> lexemes = sentence.getSentenceUnits(); //累积词元最低级for (int i = 0; i < lexemes.size(); i++) {Lexeme lexeme = lexemes.get(i);currentLexemeType = lexeme.getLexemeType();String content = lexeme.getContent();switch (currentLexemeType) { case CHINESE: //若当前词元为中文String pinyin = convertSmartAll(content); //转成拼音(pinyin4j)chineseSearch.append(content); //append到chineseSearch字段wholeSearch.append(pinyin); //append到wholeSearch字段acronymSearch.append(pinyin.charAt(0)); //append到acronymSearch字段chineseFilter.append(content).append("%"); //append到chineseFilter字段break;case WHOLE: //若为拼音 同理中文wholeSearch.append(content);acronymSearch.append(content.charAt(0));pinyinFilter.append(content).append("%");break;case ACRONYM: //同理acronymSearch.append(content);break;}//将lastLexemeType 转换成当前词元和当前lastLexemeType中的第一级别的LexeType,因为搜索时需要词元最低级lastLexemeType = LexemeType.changeDown(lastLexemeType, currentLexemeType); //new searchOptionsPinyinWordAnalyzeSearchOptions options = new PinyinWordAnalyzeSearchOptions(chineseSearch.toString(), wholeSearch.toString(), acronymSearch.toString(),chineseFilter.toString(), pinyinFilter.toString(), lastLexemeType);// 结果出来啦。。。List<WordClickCount> wordClickCounts = mapper.searchByClickCount(options);

测试一下:

    @Testpublic void analyzeAndSearchTest() throws Exception {List<List<WordClickCount>> results = pinyinWordService.analyzeSearch("xiugaishoujihao"); //为了初始化 pinyin4jlong start1 = System.currentTimeMillis();for (int i = 0; i < 100; i++) {long start = System.currentTimeMillis();List<List<WordClickCount>> results1 = pinyinWordService.analyzeSearch("xiugais机haoqyxgai修改");long end = System.currentTimeMillis();System.out.println(end - start + " ms");}long end1 = System.currentTimeMillis();System.out.println(end1 - start1 + " ms");}

测试结果

144703_cvyI_3001485.png

测试分解100条 11个词元的用户输入,话费22.1秒,平均每个221ms,效果还行

未来优化:

在sql中,使用了表关联和count操作,当数据量比较大的时候,可以考虑将pinyinword 加一个字段,每天跑定时把count update到pinyinword表中,这样可以对pinyinword进行单表查询了

参考资料:

谈谈我做拼音搜索的一点经验

LC Analysis for Elasticsearch

转载于:https://my.oschina.net/u/3001485/blog/783478

http://www.jmfq.cn/news/4780009.html

相关文章:

  • python教程/武汉网站营销seo方案
  • 网站备案条件/佛山全网营销推广
  • 网站打开403/简述优化搜索引擎的方法
  • 网页制作工具的选择与网站整体网络没有关系/武汉网站推广
  • 公司网站建设意见和建议/计算机编程培训学校哪家好
  • 四川建设工程网上合同备案网站/企业网页设计报价
  • 网站的整体风格/江苏搜索引擎优化公司
  • 赣州网站建设效果/腾讯新闻潍坊疫情
  • 建企业网站的步骤/十大接单平台
  • 重庆公司网站制作公司/会计培训班一般多少钱
  • 网站建设怎么谈/百度培训
  • 哪些行业需要做网站/云计算培训费用多少钱
  • 篇高端网站愿建设/网络推广优化网站
  • 深圳网站设计招聘信息/苏州百度推广服务中心
  • 请人做网站花多少钱/抖音关键词优化排名
  • 东莞怎样做网站建设/seo常用工具网站
  • 学校开发网站公司/单页面seo搜索引擎优化
  • 有关做美食的网站有哪些/全球网络营销公司排行榜
  • 网站运营策划/网站优化排名推荐
  • 邢台做网站哪里便宜/引流人脉推广软件
  • 如何做多语言网站/集客营销软件官方网站
  • 手工网站怎样做三角包/营销网站建设
  • 小型企业管理系统/seo顾问是什么职业
  • 刚做的网站为什么百度搜不到/十大技能培训机构排名
  • 网站建设服务领域/微信推广怎么弄
  • 美国网站服务器/专门做排名的软件
  • 动态网站建设试卷/广州头条新闻最新
  • 如何做游戏试玩网站/微信引流主动被加软件
  • 哪个网站可做密丸/东莞市网络营销公司
  • 南宁商城网站建设/营销咨询公司排名前十