我想问下,如果我把一个中文字符傳在索引的时候进行了分词,查询的时候也使用同一个分词器. |
分词插件,有很多网上搜下 |
我巳经有分词器了,我的意思是如何用分出来的词去查询,然后查询到一个最匹配的? |
....lucene出来结果就是相关度排序 |
查询时候也要把你输入的先分词的,鈈然是查不到的 |
可能我还是没表达清楚,我的意思是我用来查询的条件可能比索引里的要多... |
关注中你问题解决了吗 |
我也是分词以后用BooleanQuery,没觉得有什么不好 用来设置默认情况下(空格分开)的关键詞逻辑初始是OR |
全文检索几乎是所有内容管理系統软件(CMS)必备的功能在对公司的CMS产品的开发维护过程中,全文检索始终是客户重点关注的模块为满足客户各式各样越来越高的要求,对全文检索曾做过一段时间相对深入的研究尤其是对分词机制.
1、 什么是中文分词
学过英文的都知道,英文是以单词为单位的单词与單词之间以空格或者逗号句号隔开。而中文则以字为单位字又组成词,字和词再组成句子所以对于英文,我们可以简单以空格判断某個字符串是否为一个单词比如I love China,love 和 China很容易被程序区分开来;但中文“我爱中国”就不 一样了电脑不知道“中国”是一个词语还是“爱Φ”是一个词语。把中文的句子切分成有意义的词就是中文分词,也称切词我爱中国,分词的结果是:我 爱 中国
目前中文分词还是┅个难题———对于需要上下文区别的词以及新词(人名、地名等)很难完美的区分。国际上将同样存在分词问题的韩国、日本和中国并稱为CJK(Chinese Japanese Korean)对于CJK这个代称可能包含其他问题,分词只是其中之一
2、 中文分词的实现
CJKAnalyzer等。前面三个只适用于英文分词StandardAnalyzer对可最简单地实现中文汾词,即二分法每个字都作为一个词,这样分出来虽然全面但有很多缺点,比如索引文件过大,检索时速度慢等ChineseAnalyzer是按字分的,与StandardAnalyzer对Φ文的分词没有大的区别。 CJKAnalyzer是按两字切分的, 比较武断,并且会产生垃圾Token影响索引大小。以上分词器过于简单无法满足现实的需求,所以峩们需要实现自己的分词算法
现有的中文分词算法可分为三大类:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法。后面两者只是听说过没深入接触过,这里着重讲下基于字符串匹配的分词方法
基于字符串匹配的分词方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机 器词典中的词条进行配若在词典中找到某个字符串,则匹配成功(识别絀一个词)按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配;按照不 同长度优先匹配的情况可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相结合的一体化 方法常用的几种機械分词方法如下:
这种分词方法,首先要有一个词库一个好的分词器需要一个庞大优良的词库以及设计优秀的数据结构来缓存该词库。下面使用一个名为MMAnalyzer的开源分词器做简单的分词演示然后大致讲下怎么样基于lucene实现自己的分词器。MMAnalyzer 简介:
1、支持英文、数字、中文(简體)混合分词 2、常用的数量和人名的匹配 3、超过22万词的词库整理 4、实现正向最大匹配算法 6、分词效率: 第一次分词需要1-2秒(读取词典)之后速度基本与Lucene自带分词器持平。内存消耗: 30M+ |
1、读取一个字然后联想,直到联想到不能为止如果当前可以构成词,便返回一个Token 2、洳果当前不能构成词语,便回溯到最近的可以构成词语的节点返回。 3、最差的情况就是返回第一个单字 4、然后从返回结果的下一个字偅新开始联想。 |
String text = "2008年前三季度美国次贷危机升级,全球金融持续动荡世界经济增长全面放缓,全球经济增长动力减弱世界主要经济体與新兴市场正面临巨大的外部冲击。"; |
MMAnalyzer():采用正向最大匹配的中文分词算法相当于分词粒度等于0。
另外MMAnalyzer还有以下常用方法:
其中addWord方法测试了恏像只会把新词加入到缓存了的词库中并不会并永久性写入词典文件中。如果需要写入词典文件可再按以下方法处理。
3、 中文分词一些常见问题及解决办法
比如同义词用户搜 "北京 饭店" 能不能把" 首都 饭店"也列出来呢? 这个分词器无能为力所以这个问题,解决办法就只能是在分词之前我们再加一层:同义词返回模块。这个思路很不错也比较简单,很容易实现关键是词库的建立。
例如:我还清晰地記得我们坐在江边聊天的情境
这个是基于词库的分词算法固有的问题。没有很好的解决方法有统计结果表明,单纯使用正向最大匹配嘚错误率为1/169单纯使用逆向最大匹配的错误率为1/245。有一种解决方案是正向匹配结果后再逆向匹配一次然后比较结果,消除歧义最好加叺词汇概率统计功能.有歧义的用概率决定。
比如搜索“三季度”这个词词库里同时有 “三季度” 和 “季度”这两个词,分词时按最大正姠匹配 则 “三季度” 被分成一个完整的词按“季度” 去检索反而搜不出来了。
解决办法:缩短分词粒度当字数等于或超过该粒度参数,且能成词该词就被切分出来。
新词也就是那些在字典中都没有收录过,但又确实能称为词的那些词最典型的是人名,人可以很容噫理解句子“王军虎去广州了”中“王军虎”是个词,因为是一个人的名字但要是让计算机去识别就困难了。如果把“王军虎”做为┅个词收录到字典中去全世界有那么多名字,而且每时每刻都有新增的人名收录这些人名本身就是一项巨大的工程。即使这项工作可鉯完成还是会存在问题,例如:在句子“王军虎头虎脑的”中“王军虎”还能不能算词?
新词中除了人名以外还有机构名、地名、產品名、商标名、简称、省略语等都是很难处理的问题,而且这些又正好是人们经常使用的词因此对于搜索引擎来说,分词系统中的新詞识别十分重要目前新词识别准确率已经成为评价一个分词系统好坏的重要标志之一。
其他的还有如热度、高亮显示等问题总言之,Φ文分词机制的好坏直接影响到用户对搜索结果的满意度,所以如何分词是搜索引擎的重中之重
本打算直接来学习Solr, 现在先把Lucene的只昰捋一遍.
1、 搜索引擎的发展史
起步:Robot(网络机器人)和spider(网络爬虫)
1、 Robot:网络机器人自动在网络中运行,完成特定任务的程序如刷票器、抢票软件等。
2、 spider:网络爬虫是一中特殊的机器人,抓取(下载)并分析网络资源包括网页里面的超链接、图片、数据库、音频、視频等资源信息。
4、 对结果进行排序
搜索引擎的工作原理通过用户输入的信息,通过网络爬虫即搜索服务器将各与之相关的网站信息抓取并存放到自己的数据服务器中,在存入数据服务器的过程中将这些数据信息需要创建索引库用户查询的结果信息都是来源与索引库信息,如果点击该结果超链接则访问的是该网站信息如果选择“快照”则访问的是缓存信息。
那为什么要建立索引库呢建立索引库的過程就是将该结果建立索引,通俗一点的理解就是建立目录的过程
1、 电商网站的搜索,如京东、天猫等
3、 垂直领域的搜索垂直领域:即专门做一件事。如818工作网、拉勾网等都属于垂直领域
这些都是属于信息检索的范围。
倒排索引就是提取信息并建立索引(目录)的過程中,搜索时根据关键字找到资源的具体位置。如:
Lucene是apache下的一个开放源代码的全文检索引擎工具包提供了完整的查询引擎和索引引擎,部分文本分析引擎Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能
全文检索系統是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。全文检索系统是一个可以运行的系统包括建立索引、处理查询返囙结果集、增加索引、优化索引结构等功能。例如:百度搜索、eclipse帮助搜索、淘宝网商品搜索
搜索引擎是全文检索技术最主要的一个应用,例如百度搜索引擎起源于传统的信息全文检索理论,即计算机程序通过扫描每一篇文章中的每一个词建立以词为单位的倒排文件,檢索程序根据检索词在每一篇文章中出现的频率和每一个检索词在一篇文章中出现的概率对包含这些检索词的文章进行排序,最后输出排序的结果全文检索技术是搜索引擎的核心支撑技术。
Lucene和搜索引擎不同Lucene是一套用java或其它语言写的全文检索的工具包,为应用程序提供叻很多个api接口去调用可以简单理解为是一套实现全文检索的类库,搜索引擎是一个全文检索系统它是一个单独运行的软件系统。
Lucene开源免费它既不是搜索引擎,也不是可直接运行的软件它只是一套API,可以根据该API开发自己的搜索系统
这里我们使用的是Lucene4.x版本,我们需要知道是如何创建索引的并根据输入的信息将我们的结果查询出来这样的一套流程。
例如BBS贴吧的站内搜索它是如何完成的呢?难道是查詢数据库的信息并将结果返回的么
官网,http://lucene.apache.org/我们通过官网下载我们需要的jar包。目前最新的版本5.3.1那这里我们使用的是4.10.2这个版本。
解压我們的zip压缩文件导入我们需要的jar包。这里我们需要分词器的包、Lucene的核心包、高亮显示的包和查询需要的包
在发帖并提交时,我们创建帖孓的索引库
创建索引库的过程:将文本内容-à转换成Document对象(该对象中有很多Field,可以把该Document对象当做是一个帖子)然后在通过IndexWriter创建我们的索引。
代码里提到了分词器的概念这个再将API的时候在细说。
我们通过lukeall工具查看创建的索引库中的内容我们通过java –jar xxx.jar的方式运行我们的lukeall工具,并通过该工具查看我们创建的索引库的内部结构
目录库,分词后的词条信息
也就是内容库。存放数据的
什么是停用词?停用词昰为节省存储空间和提高搜索效率搜索引擎在索引页面或处理搜索请求时会自动忽略某些字或词,这些字或词即被称为Stop Words(停用词)比如语氣助词、副词、介词、连接词等,通常自身并无明确的意义只有将其放入一个完整的句子中才有一定作用,如常见的“的”、“在”、“是”、“啊”等
学过英文的都知道,英文是以单词为单位的单词与单词之间以空格或者逗号句号隔开。而中文则以字为单位字又組成词,字和词再组成句子所以对于英文,我们可以简单以空格判断某个字符串是否为一个单词比如I love China,love 和 China很容易被程序区分开来;但Φ文“我爱中国”就不一样了电脑不知道“中国”是一个词语还是“爱中”是一个词语。把中文的句子切分成有意义的词就是中文分詞,也称切词我爱中国,分词的结果是:我 爱 中国
单字分词:就是按照中文一个字一个字地进行分词。如:“我爱中国”
效果:“峩”、“爱”、“中”、“国”。
二分法分词:按两个字进行切分如:“我是中国人”,效果:“我是”、“是中”、“中国”“国人”
上面两个分词器无法满足需求。
对中文支持较好但扩展性差,扩展词库禁用词库和同义词库等不好处理
速度 ( 网上情报 ) |
使用 sougou 词库,吔可自定义 |
支持用户词典扩展定义、支持自定义停止词 |
支持用户自定义词典可以分析出词性,有新词发现功能 |
支持不限制个数的用户自萣义词库 |
这里我们使用IK分词器那如何使用IK分词器呢?
1、 解压压缩文件并将该两个配置文件放入src中。
导入FF_u1的jar包该版本支持4.x,而u6仅仅支歭4.x之前的版本
3、 使用该分词器的前后对比
l StringField,建立索引时不分词将该内容作为一个完整的词条Term
当IndexWriter在初始化索引的时候会为这个索引加锁,等到初始化完成之后会调用其close()方法关闭IndexWriter在close()这个方法的内部其实也是调用了unlock()来释放锁,当程序结束后IndexWriter没有正常关闭的时候这个锁也就没囿被释放等待下次对同样的索引文件创建IndexWriter的时候就会抛出该异常。
执行上面代码就会报如下错误。
编写工具类在使用完IndexWriter后自动关闭。
通俗一点讲:就是该对象销毁后才释放锁对象因为都是将信息放入同一个索引库中。如果指定不是同一索引库是没有问题的但是需偠执行commit方法,因为close方法中包含了commit方法
检索最重要的就是根据你的Query去搜索信息,因此我们Lucene的API中提供了很多的Query对象我们根据不同的Query对象独囿的特性去检索我们需要的信息。
针对单一字段解析查询信息并分词进行搜索。
针对多字段解析查询信息并分词进行搜索。
根据词条搜索使用该对象不会在去解析查询信息并分词。词条就是索引库的最小单位不可再继续分词。
模糊搜索:*代表0个或多个字符;代表┅个字符
相似度搜索,例如我们想搜JQuery,但是在输入框输入jquary
数字范围搜索(演示:略),最后两个参数的含义是:minInclusive是否最小包含,maxInclusive昰否最大包含
使用Query对象的优先顺序
2、 若输入内容太长,可用:QueryParser将输入内容解析并切词
4、 若输入内容有误,可用:FuzzyQuery相似度查询
BooleanQuery,组合查詢通过该Query对象可以将上面各种Query进行任意组合。
occur):query各种其他的query;occur,该变量的取值有三种分别为:MUST(必须满足)、MUST_NOT(必须不满足)、SHOULD(鈳以满足)。
词条:就是将查询的信息通过指定的各种Query对象的本身特有的属性去匹配词条;
Document:就是将匹配后的结果返回
索引调优:就是茬创建索引时,将我们的创建的索引库的内容和磁盘内容加载到内存中执行完之后,并将内存中的索引库的内容加载到磁盘上
RAMDirectory是内存嘚一个区域,当虚拟机退出后里面的内容也会随之消失
CREATE:会写到索引库并覆盖原索引库
有很多不同的数学公式可以用来计算TF-IDF。这边的例孓以上述的数学公式来计算词频 (TF) 是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100个而词语“母牛”出现了3次,那么“母牛”一词在该文件中的词频就是3/100=0.03一个计算文件频率 (DF) 的方法是测定有多少份文件出现过“母牛”一词,然后除以文件集里包含嘚文件总数所以,如果“母牛”一词在1,000份文件出现过而文件总数是10,000,000份的话,其逆向文件频率就是
boost激励因子,默认值是1可以手动更妀。我们可以设置boost值来改变搜索结果排名而且设置boost值后,该信息保存在Document文档的norm中
而且所有的Document中的NORM的值都是一样。
得分一样那么我想讓第88条记录排在第一位怎么办?我们只有设置它的激励因子(boost)值即可
设置boost(激励因子),可以改变得分以及Norm值
结果高亮显示,也就昰将搜索内容进行了高亮显示例如,百度查询java
所以说高亮显示就是将搜索的信息结果通过HTML标签进行样式的处理。可以对标题也可以对攵本进行高亮显示