a) 索引流程html
b) 搜索流程java
a) 索引实现mysql
b) 搜索实现git
a) 分词介绍github
b) IK分词器web
原来的方式实现搜索功能,咱们的搜索流程以下图:算法
上图就是原始搜索引擎技术,若是用户比较少并且数据库的数据量比较小,那么这种方式实现搜索功能在企业中是比较常见的。spring
可是数据量过多时,数据库的压力就会变得很大,查询速度会变得很是慢。咱们须要使用更好的解决方案来分担数据库的压力。sql
如今的方案(使用Lucene),以下图 数据库
为了解决数据库压力和速度的问题,咱们的数据库就变成了索引库,咱们使用Lucene的API的来操做服务器上的索引库。这样彻底和数据库进行了隔离。
所谓顺序扫描,例如要找内容包含一个字符串的文件,就是一个文档一个文档的看,对于每个文档,从头看到尾,若是此文档包含此字符串,则此文档为咱们要找的文件,接着看下一个文件,直到扫描完全部的文件。
这种方法是顺序扫描方法,数据量大就搜索慢。
先搜索文档、再今后文档找词
先举一个栗子
例如咱们使用新华字典查询汉字,新华字典有偏旁部首的目录(索引),咱们查字首先查这个目录,找到这个目录中对应的偏旁部首,就能够经过这个目录中的偏旁部首找到这个字所在的位置(文档)。
先词后文档
如今有两篇文档:
Doc1: When in Rome, do as the Romans do.
Doc2: When do you come back from Rome?
Lucene会对以上两篇文档创建倒排索引
索引结构以下图:
一、 提取资源中关键信息, 创建索引 (目录)
二、 搜索时,根据关键字(目录),找到资源的位置
应用场景 :
1、 单机软件的搜索(word中的搜索)
2、 站内搜索 (baidu贴吧、论坛、 京东、 taobao)
3、 垂直领域的搜索 (818工做网) 智联 拉钩 Boss直
4、 专业搜索引擎公司 (google、baidu)
计算机索引程序经过扫描文章中的每个词,对每个词创建一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先创建的索引进行查找,并将查找的结果反馈给用户的检索方式
先建立索引 再对索引进行搜索的过程叫全文检索 (全文索引)
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础创建起完整的全文检索引擎。
目前已经有不少应用程序的搜索功能是基于 Lucene 的,好比 Eclipse 的帮助系统的搜索功能。Lucene 可以为文本类型的数据创建索引,因此你只要能把你要索引的数据格式转化的文本的,Lucene 就能对你的文档进行索引和搜索。好比你要对一些 HTML 文档,PDF 文档进行索引的话你就首先须要把 HTML 文档和 PDF 文档转化成文本格式的,而后将转化后的内容交给 Lucene 进行索引,而后把建立好的索引文件保存到磁盘或者内存中,最后根据用户输入的查询条件在索引文件上进行查询。不指定要索引的文档的格式也使 Lucene 可以几乎适用于全部的搜索应用程序。
l Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支 持和提供
l Lucene提供了一个简单却强大的应用程式接口,可以作全文索引和搜寻, 在Java开发环境里Lucene是一个成熟的免费开放源代码工具
l Lucene并非现成的搜索引擎产品,但能够用来制做搜索引擎产品
引擎产品 百度 由Lucene作的 原理 倒排索引通用的 语言不是同 Lucene实现倒排索引 (并不必定Lucene实现)
全文检索系统是按照全文检索理论创建起来的用于提供全文检索服务的软件系统,包括创建索引、处理查询返回结果集、增长索引、优化索引结构等功能。例如:百度搜索、eclipse帮助搜索、淘宝网商品搜索等。
完整的系统 百度 淘宝 京东 搜索引擎
Lucene 实现此搜索引擎系统的工具包
搜索引擎是全文检索技术最主要的一个应用,例如百度。搜索引擎起源于传统的信息全文检索理论,即计算机程序经过扫描每一篇文章中的每个词,创建以词为单位的倒排文件,检索程序根据检索词在每一篇文章中出现的频率和每个检索词在一篇文章中出现的几率,对包含这些检索词的文章进行排序,最后输出排序的结果。全文检索技术是搜索引擎的核心支撑技术。
Lucene和搜索引擎不一样,Lucene是一套用java或其它语言写的全文检索的工具包,为应用程序提供了不少个api接口去调用,能够简单理解为是一套实现全文检索的类库,搜索引擎是一个全文检索系统,它是一个单独运行的软件系统
官网: http://lucene.apache.org/
1、绿色表示索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
肯定原始内容即要搜索的内容à得到文档à建立文档à分析文档à索引文档
2、红色表示搜索过程,从索引库中搜索内容,搜索过程包括:
用户经过搜索界面à建立查询à执行搜索,从索引库搜索à渲染搜索结果
对文档索引的过程,将用户要搜索的文档内容进行索引,索引存储在索引库(index)中。
原始内容是指要索引和搜索的内容。
原始内容包括互联网上的网页、数据库中的数据、磁盘上的文件等。
从互联网上、数据库、文件系统中等获取须要搜索的原始信息,这个过程就是信息采集,采集数据的目的是为了对原始内容进行索引。
采集数据分类:
1、对于互联网上网页,可使用工具将网页抓取到本地生成html文件。
2、数据库中的数据,能够直接链接数据库读取表中的数据。
3、文件系统中的某个文件,能够经过I/O操做读取文件的内容。
在Internet上采集信息的软件一般称为爬虫或蜘蛛,也称为网络机器人,爬虫访问互联网上的每个网页,将获取到的网页内容存储起来。
Lucene不提供信息采集的类库,须要本身编写一个爬虫程序实现信息采集,也能够经过一些开源软件实现信息采集,以下:
Solr(http://lucene.apache.org/solr) ,solr是apache的一个子项目,支持从关系数据库、xml文档中提取原始数据。
Nutch(http://lucene.apache.org/nutch), Nutch是apache的一个子项目,包括大规模爬虫工具,可以抓取和分辨web网站数据。
jsoup(http://jsoup.org/ ),jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套很是省力的API,可经过DOM,CSS以及相似于jQuery的操做方法来取出和操做数据。
获取原始内容的目的是为了索引,在索引前须要将原始内容建立成文档(Document),文档中包括一个一个的域(Field),域中存储内容。
这里咱们能够将磁盘上的一个文件当成一个document,Document中包括一些Field,以下图:
注意:每一个Document能够有多个Field,不一样的Document能够有不一样的Field,同一个Document能够有相同的Field(域名和域值都相同)
将原始内容建立为包含域(Field)的文档(document),须要再对域中的内容进行分析,分析成为一个一个的单词。
好比下边的文档通过分析以下:
原文档内容:
Lucene is a Java full-text search engine. Lucene is not a complete
application, but rather a code library and API that can easily be used
to add search capabilities to applications.
分析后获得的词:
lucene、java、full、search、engine。。。。
对全部文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到Document(文档)。
建立索引是对语汇单元索引,经过词语找文档,这种索引的结构叫倒排索引结构。
倒排索引结构是根据内容(词汇)找文档,以下图:
倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它的规模较小,而文档集合较大。索引 词汇表 语汇单元要比搜索文档集合要快的多。
搜索就是用户输入关键字,从索引中进行搜索的过程。根据关键字搜索索引,根据索引找到对应的文档,从而找到要搜索的内容。
就是使用搜索的角色,用户能够是天然人,也能够是远程调用的程序。
全文检索系统提供用户搜索的界面供用户提交搜索的关键字,搜索完成展现搜索结果。以下图:
Lucene不提供制做用户搜索界面的功能,须要根据本身的需求开发搜索界面。
用户输入查询关键字执行搜索以前须要先构建一个查询对象,查询对象中能够指定查询要查询关键字、要搜索的Field文档域等,查询对象会生成具体的查询语法,好比:
name:lucene表示要搜索name这个Field域中,内容为“lucene”的文档。
desc:lucene AND desc:java 表示要搜索即包括关键字“lucene”也包括“java”的文档。
OR
搜索索引过程:
1.根据查询语法在倒排索引词典表中分别找出对应搜索词的索引,从而找到索引所连接的文档链表。
例如搜索语法为“desc:lucene AND desc:java”表示搜索出的文档中既要包括lucene也要包括java。
二、因为是AND,因此要对包含lucene或java词语的链表进行交集,获得文档链表应该包括每个搜索词语
三、获取文档中的Field域数据。
以一个友好的界面将查询结果展现给用户,用户根据搜索结果找本身想要的信息,为了帮助用户很快找到本身的结果,提供了不少展现的效果,好比搜索结果中将关键字高亮显示,百度提供的快照等。
Lucene能够在官网上下载。课程已经准备好了Lucene的文件,咱们使用的是4.10.3版本,文件位置以下图:
解压后的效果:
使用这三个文件的jar包,就能够实现lucene功能
JDK: 1.7 (Lucene4.8以上,必须使用JDK1.7及以上版本)
IDE: eclipse Mars2
数据库: MySQL
建立java工程测试便可
在电商网站中,全文检索的数据源在数据库中,须要经过jdbc访问数据库中book表的内容。
1 public class Book { 2 3 // 图书ID 4 5 private Integer id; 6 7 // 图书名称 8 9 private String name; 10 11 // 图书价格 12 13 private Float price; 14 15 // 图书图片 16 17 private String pic; 18 19 // 图书描述 20 21 private String desc; 22 23 get/set。。。 24 25 }
1 public interface BookDao { 2 3 /** 4 * 查询全部的book数据 5 * 6 * @return 7 */ 8 9 List<Book> queryBookList(); 10 11 }
使用jdbc实现
1 public class BookDaoImpl implements BookDao { 2 3 @Override 4 5 public List<Book> queryBookList() { 6 7 // 数据库连接 8 9 Connection connection = null; 10 11 // 预编译statement 12 13 PreparedStatement preparedStatement = null; 14 15 // 结果集 16 17 ResultSet resultSet = null; 18 19 // 图书列表 20 21 List<Book> list = new ArrayList<Book>(); 22 23 24 25 try { 26 27 // 加载数据库驱动 28 29 Class.forName("com.mysql.jdbc.Driver"); 30 31 // 链接数据库 32 33 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/solr", "root", "root"); 34 35 36 // SQL语句 37 38 String sql = "SELECT * FROM book"; 39 40 // 建立preparedStatement 41 42 preparedStatement = connection.prepareStatement(sql); 43 44 // 获取结果集 45 46 resultSet = preparedStatement.executeQuery(); 47 48 // 结果集解析 49 50 while (resultSet.next()) { 51 52 Book book = new Book(); 53 54 book.setId(resultSet.getInt("id")); 55 56 book.setName(resultSet.getString("name")); 57 58 book.setPrice(resultSet.getFloat("price")); 59 60 book.setPic(resultSet.getString("pic")); 61 62 book.setDesc(resultSet.getString("desc")); 63 64 list.add(book); 65 66 } 67 68 } catch (Exception e) { 69 70 e.printStackTrace(); 71 72 } 73 74 return list; 75 76 } 77 78 }
package com.wxs.text; import java.io.File; import java.util.ArrayList; import java.util.List; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import org.junit.Test; import org.wltea.analyzer.lucene.IKAnalyzer; import com.wxs.dao.BookDao; import com.wxs.dao.BookDaoImpl; import com.wxs.pojo.Book; /** *@author 做者: WangXS *@version 日期: 2018年10月9日 下午4:29:05 */ public class CreateIndexTest { @Test public void testCreateIndex() throws Exception { //1.采集数据 BookDao bd = new BookDaoImpl(); List<Book> bookList = bd.queryBookList(); //2.建立Document文档对象 List<Document> documents = new ArrayList<>(); for (Book book : bookList) { Document document = new Document(); // Document文档中添加Field域 // 图书Id // Store.YES:表示存储到文档域中 document.add(new TextField("id", book.getId().toString(), Store.YES)); // 图书名称 document.add(new TextField("name", book.getName().toString(), Store.YES)); // 图书价格 document.add(new TextField("price", book.getPrice().toString(), Store.YES)); // 图书图片地址 document.add(new TextField("pic", book.getPic().toString(), Store.YES)); // 图书描述 document.add(new TextField("desc", book.getDesc().toString(), Store.YES)); // 把Document放到list中 documents.add(document); } //3.建立分析器(分词器) //StandardAnalyzer standardAnalyzer = new StandardAnalyzer(); IKAnalyzer analyzer = new IKAnalyzer(); //4.建立IndexWriterConfig配置信息类 IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer); //5.建立Directory对象,声明索引库存储位置 Directory directory = FSDirectory.open(new File("F:\\temp\\index")); //6.建立IndexWriter写入对象 IndexWriter indexWriter = new IndexWriter(directory, config); //7.把Document写入到索引库中 for (Document document : documents) { indexWriter.addDocument(document); } //8.释放资源 indexWriter.close(); } }
执行效果:
在文件夹中出现了如下文件,表示建立索引成功
Luke做为Lucene工具包中的一个工具(http://www.getopt.org/luke/),能够经过界面来进行索引文件的查询、修改
Lucene能够经过query对象输入查询语句。同数据库的sql同样,lucene也有固定的查询语法:
最基本的有好比:AND, OR, NOT 等(必须大写)
举个栗子:
用户想找一个desc中包括java关键字和lucene关键字的文档。
它对应的查询语句:desc:java AND desc:lucene
和索引过程的分词同样,这里要对用户输入的关键字进行分词,通常状况索引和搜索使用的分词器一致。
好比:输入搜索关键字“java学习”,分词后为java和学习两个词,与java和学习有关的内容都搜索出来了,以下:
1. 建立Query搜索对象
2. 建立Directory流对象,声明索引库位置
3. 建立索引读取对象IndexReader
4. 建立索引搜索对象IndexSearcher
5. 使用索引搜索对象,执行搜索,返回结果集TopDocs
6. 解析结果集
7. 释放资源
IndexSearcher搜索方法以下:
方法 |
说明 |
indexSearcher.search(query, n) |
根据Query搜索,返回评分最高的n条记录 |
indexSearcher.search(query, filter, n) |
根据Query搜索,添加过滤策略,返回评分最高的n条记录 |
indexSearcher.search(query, n, sort) |
根据Query搜索,添加排序策略,返回评分最高的n条记录 |
indexSearcher.search(booleanQuery, filter, n, sort) |
根据Query搜索,添加过滤策略,添加排序策略,返回评分最高的n条记录 |
代码实现
1 package com.wxs.text; 2 3 import java.io.File; 4 5 import org.apache.lucene.analysis.Analyzer; 6 import org.apache.lucene.analysis.standard.StandardAnalyzer; 7 import org.apache.lucene.document.Document; 8 import org.apache.lucene.index.DirectoryReader; 9 import org.apache.lucene.index.IndexReader; 10 import org.apache.lucene.queryparser.classic.QueryParser; 11 import org.apache.lucene.search.IndexSearcher; 12 import org.apache.lucene.search.Query; 13 import org.apache.lucene.search.ScoreDoc; 14 import org.apache.lucene.search.TopDocs; 15 import org.apache.lucene.store.Directory; 16 import org.apache.lucene.store.FSDirectory; 17 import org.junit.Test; 18 19 /** 20 *@author 做者: WangXS 21 *@version 日期: 2018年10月10日 下午3:38:00 22 */ 23 public class SearchIndexTest { 24 @Test 25 public void testSearchIndex() throws Exception { 26 //1. 建立Query搜索对象 27 // 建立分词器 28 Analyzer analyzer = new StandardAnalyzer(); 29 // 建立搜索解析器,第一个参数:默认Field域,第二个参数:分词器 30 QueryParser queryParser = new QueryParser("desc", analyzer); 31 Query query = queryParser.parse("desc:java AND lucene"); 32 //2. 建立Directory流对象,声明索引库位置 33 Directory directory = FSDirectory.open(new File("F:\\temp\\index")); 34 //3. 建立索引读取对象IndexReader 35 IndexReader indexReader = DirectoryReader.open(directory); 36 //4. 建立索引搜索对象IndexSearcher 37 IndexSearcher search = new IndexSearcher(indexReader); 38 //5. 使用索引搜索对象,执行搜索,返回结果集TopDocs 39 // 第一个参数:搜索对象,第二个参数:返回的数据条数,指定查询结果最顶部的n条数据返回 40 TopDocs topDocs = search.search(query, 5); 41 System.out.println("查询到的数据总条数是:" + topDocs.totalHits); 42 //6. 解析结果集 43 ScoreDoc[] scoreDocs = topDocs.scoreDocs; 44 for (ScoreDoc scoreDoc : scoreDocs) { 45 //获取文档 46 int docId = scoreDoc.doc; 47 Document doc = search.doc(docId); 48 System.out.println("============================="); 49 System.out.println("docID:" + docId); 50 System.out.println("bookId:" + doc.get("id")); 51 System.out.println("name:" + doc.get("name")); 52 System.out.println("price:" + doc.get("price")); 53 System.out.println("pic:" + doc.get("pic")); 54 // System.out.println("desc:" + doc.get("desc")); 55 } 56 //7. 释放资源 57 indexReader.close(); 58 } 59 }
在对Docuemnt中的内容进行索引以前,须要使用分词器进行分词 ,分词的目的是为了搜索。分词的主要过程就是先分词后过滤。
l 分词:采集到的数据会存储到document对象的Field域中,分词就是将Document中Field的value值切分红一个一个的词。
l 过滤:包括去除标点符号过滤、去除停用词过滤(的、是、a、an、the等)、大写转小写、词的形还原(复数形式转成单数形参、过去式转成如今式。。。)等。
什么是停用词?停用词是为节省存储空间和提升搜索效率,搜索引擎在索引页面或处理搜索请求时会自动忽略某些字或词,这些字或词即被称为Stop Words(停用词)。好比语气助词、副词、介词、链接词等,一般自身并没有明确的意义,只有将其放入一个完整的句子中才有必定做用,如常见的“的”、“在”、“是”、“啊”等。
对于分词来讲,不一样的语言,分词规则不一样。Lucene做为一个工具包提供不一样国家的分词器,本例子使用StandardAnalyzer,它能够对用英文进行分词。
以下是org.apache.lucene.analysis.standard.standardAnalyzer的部分源码:
1 @Override 2 3 protected TokenStreamComponents createComponents(final String fieldName, final Reader reader) { 4 5 final StandardTokenizer src = new StandardTokenizer(getVersion(), reader); 6 7 src.setMaxTokenLength(maxTokenLength); 8 9 TokenStream tok = new StandardFilter(getVersion(), src); 10 11 tok = new LowerCaseFilter(getVersion(), tok); 12 13 tok = new StopFilter(getVersion(), tok, stopwords); 14 15 return new TokenStreamComponents(src, tok) { 16 17 @Override 18 19 protected void setReader(final Reader reader) throws IOException { 20 21 src.setMaxTokenLength(StandardAnalyzer.this.maxTokenLength); 22 23 super.setReader(reader); 24 25 } 26 27 }; 28 29 }
Tokenizer就是分词器,负责将reader转换为语汇单元即进行分词处理,Lucene提供了不少的分词器,也可使用第三方的分词,好比IKAnalyzer一个中文分词器。
TokenFilter是分词过滤器,负责对语汇单元进行过滤,TokenFilter能够是一个过滤器链儿,Lucene提供了不少的分词器过滤器,好比大小写转换、去除停用词等。
以下图是语汇单元的生成过程:
从一个Reader字符流开始,建立一个基于Reader的Tokenizer分词器,通过三个TokenFilter生成语汇单元Tokens。
好比下边的文档通过分析器分析以下:
输入关键字进行搜索,当须要让该关键字与文档域内容所包含的词进行匹配时须要对文档域内容进行分析,须要通过Analyzer分析器处理生成语汇单元(Token)。分析器分析的对象是文档中的Field域。当Field的属性tokenized(是否分词)为true时会对Field值进行分析,以下图:
对于一些Field能够不用分析:
1、不做为查询条件的内容,好比文件路径
2、不是匹配内容中的词而匹配Field的总体内容,好比订单号、身份证号等。
对搜索关键字进行分析和索引分析同样,使用Analyzer对搜索关键字进行分析、分词处理,使用分析后每一个词语进行搜索。好比:搜索关键字:spring web ,通过分析器进行分词,得出:spring web拿词去索引词典表查找 ,找到索引连接到Document,解析Document内容。
对于匹配总体Field域的查询能够在搜索时不分析,好比根据订单号、身份证号查询等。
注意:搜索使用的分析器要和索引使用的分析器一致。
学过英文的都知道,英文是以单词为单位的,单词与单词之间以空格或者逗号句号隔开。因此对于英文,咱们能够简单以空格判断某个字符串是否为一个单词,好比I love China,love 和 China很容易被程序区分开来。
而中文则以字为单位,字又组成词,字和词再组成句子。中文“我爱中国”就不同了,电脑不知道“中国”是一个词语仍是“爱中”是一个词语。
把中文的句子切分红有意义的词,就是中文分词,也称切词。我爱中国,分词的结果是:我、爱、中国。
l StandardAnalyzer:
单字分词:就是按照中文一个字一个字地进行分词。如:“我爱中国”,
效果:“我”、“爱”、“中”、“国”。
l CJKAnalyzer
二分法分词:按两个字进行切分。如:“我是中国人”,效果:“我是”、“是中”、“中国”“国人”。
上边两个分词器没法知足需求。
l SmartChineseAnalyzer
对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等很差处理
l paoding: 庖丁解牛最新版在 https://code.google.com/p/paoding/ 中最多支持Lucene 3.0,且最新提交的代码在 2008-06-03,在svn中最新也是2010年提交,已通过时,不予考虑。
l mmseg4j:最新版已从 https://code.google.com/p/mmseg4j/ 移至 https://github.com/chenlb/mmseg4j-solr,支持Lucene 4.10,且在github中最新提交代码是2014年6月,从09年~14年一共有:18个版本,也就是一年几乎有3个大小版本,有较大的活跃度,用了mmseg算法。
l IK-analyzer: 最新版在https://code.google.com/p/ik-analyzer/上,支持Lucene 4.10从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词 歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。 可是也就是2012年12月后没有在更新。
l ansj_seg:最新版本在 https://github.com/NLPchina/ansj_seg tags仅有1.1版本,从2012年到2014年更新了大小6次,可是做者本人在2014年10月10日说明:“可能我之后没有精力来维护ansj_seg了”,如今由”nlp_china”管理。2014年11月有更新。并未说明是否支持Lucene,是一个由CRF(条件随机场)算法所作的分词算法。
l imdict-chinese-analyzer:最新版在 https://code.google.com/p/imdict-chinese-analyzer/ , 最新更新也在2009年5月,下载源码,不支持Lucene 4.10 。是利用HMM(隐马尔科夫链)算法。
l Jcseg:最新版本在git.oschina.net/lionsoul/jcseg,支持Lucene 4.10,做者有较高的活跃度。利用mmseg算法。
IKAnalyzer继承Lucene的Analyzer抽象类,使用IKAnalyzer和Lucene自带的分析器方法同样,将Analyzer测试代码改成IKAnalyzer测试中文分词效果。
若是使用中文分词器ik-analyzer,就须要在索引和搜索程序中使用一致的分词器:IK-analyzer。
若是想配置扩展词和停用词,就建立扩展词的文件和停用词的文件。
注意:不要用window自带的记事本保存扩展词文件和停用词文件,那样的话,格式中是含有bom的。
从ikanalyzer包中拷贝配置文件
拷贝到资源文件夹中
IKAnalyzer.cfg.xml配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 4 5 <properties> 6 7 <comment>IK Analyzer 扩展配置</comment> 8 9 <!--用户能够在这里配置本身的扩展字典 --> 10 11 <entry key="ext_dict">ext.dic;</entry> 12 13 14 15 <!--用户能够在这里配置本身的扩展中止词字典--> 16 17 <entry key="ext_stopwords">stopword.dic;</entry> 18 19 20 21 </properties>
中文词库,添加新词的地方
stopword.dic是存放停用词的地方