在创建索引的时候需要用法哦分词器,在使用字符串搜索的时候也会用到分词器,并且这两个地方要使用同一个分词器,否则可能会搜索不出来结果;
分词器的作用是把一段文本中的词按规则取出所包含的所有词,对应的是Analyzer类,这是一个抽象类,切分词的具体规则是由子类实现的,所有对于不同语言的规则,要有不同的分词器;
分词器为中文分词器和英文分词器:
英文分词器是按照词汇切分,同时作词干提取,也就是将单词末尾的变化还原,使其能搜索出来,另外各种分词器对英文都支持的比较好;
中文分词器很多实现方式,实现原理基本差不多,都是Analyzer的子类:
标椎分词器:也叫单字分词,将中文一个字一个字的分词; new StandardAnalyzer();
简单分词器:根据标点符号进行分词; new SimpleAnalyzer();
二分法分词器:按照两个字进行分词; new CJKAnalyzer();
停用词分词器:和简单分词器很像,根据被忽略停用的词进行分词; new StopAnalyzer();
空格分词器:根据空格进行分词; new WhitespaceAnalyzer();
IK中文分词器:分为两种实现,一种采用智能切分,另一种是最细粒度切分算法; new IKAnalyzer();
package com.zn; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import java.io.IOException; public class AnalyzerTest { public static void main(String[] args) throws IOException { //1、创建一个Analyzer对象 Analyzer analyzer=new StandardAnalyzer(); //2、调用Analyzer对象的tokenStream方法获取TokenStream对象,此对象包含了所有分词结果 TokenStream tokenStream = analyzer.tokenStream("", "The spring Framework provides a comprehensive programming and configuration model."); //3、给tokenStream对象设置一个指针,指针在哪当前就在哪一个分词上 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); //4、调用tokenStream对象的reset方法,重置指针,不调用会报错 tokenStream.reset(); //5、利用while循环,拿到分词列表的结果 incrementToken方法返回值如果为false代表读取完毕,true为没有读取完毕 while (tokenStream.incrementToken()){ System.out.println(charTermAttribute.toString()); } //6、关闭 tokenStream.close(); } }
效果展示:
① StandardAnalyzer:
单字分词:就是按照中文一个字一个字地进行分词。如:“我爱中国”,
效果:“我”、“爱”、“中”、“国”。
② SmartChineseAnalyzer
对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等不好处理
package com.zn; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import java.io.IOException; /*默认中文分析器*/ public class AnalyzerTest { public static void main(String[] args) throws IOException { //1、创建一个Analyzer对象 Analyzer analyzer=new StandardAnalyzer(); //2、调用Analyzer对象的tokenStream方法获取TokenStream对象,此对象包含了所有分词结果 TokenStream tokenStream = analyzer.tokenStream("", "啦啦啦我爱中国我爱中国!"); //3、给tokenStream对象设置一个指针,指针在哪当前就在哪一个分词上 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); //4、调用tokenStream对象的reset方法,重置指针,不调用会报错 tokenStream.reset(); //5、利用while循环,拿到分词列表的结果 incrementToken方法返回值如果为false代表读取完毕,true为没有读取完毕 while (tokenStream.incrementToken()){ System.out.println(charTermAttribute.toString()); } //6、关闭 tokenStream.close(); } }
效果展示:
<!-- https://mvnrepository.com/artifact/com.jianggujin/IKAnalyzer-lucene --> <dependency> <groupId>com.jianggujin</groupId> <artifactId>IKAnalyzer-lucene</artifactId> <version>8.0.0</version> </dependency>
package com.zn; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.wltea.analyzer.lucene.IKAnalyzer; import java.io.IOException; public class AnalyzerTest { public static void main(String[] args) throws IOException { //1、创建一个Analyzer对象 Analyzer analyzer=new IKAnalyzer(); //2、调用Analyzer对象的tokenStream方法获取TokenStream对象,此对象包含了所有分词结果 TokenStream tokenStream = analyzer.tokenStream("", "啦啦啦我爱中国我爱中国!"); //3、给tokenStream对象设置一个指针,指针在哪当前就在哪一个分词上 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); //4、调用tokenStream对象的reset方法,重置指针,不调用会报错 tokenStream.reset(); //5、利用while循环,拿到分词列表的结果 incrementToken方法返回值如果为false代表读取完毕,true为没有读取完毕 while (tokenStream.incrementToken()){ System.out.println(charTermAttribute.toString()); } //6、关闭 tokenStream.close(); } }
hotword.dic和ext_stopword.dic文件的格式为UTF-8,注意是无BOM 的UTF-8 编码。
也就是说禁止使用windows记事本编辑扩展词典文件
package com.zn; import org.apache.commons.io.FileUtils; import org.apache.lucene.document.*; 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.wltea.analyzer.lucene.IKAnalyzer; import java.io.File; import java.io.IOException; /** * 创建索引 */ public class CreatLucene { public static void main(String[] args) throws IOException { //步骤一:创建Directory对象,用于指定索引库的位置 Directory directory= FSDirectory.open(new File("E:\\accp\\Y2\\进阶内容\\Lucene\\Lucene\\Index").toPath()); //步骤二:创建一个IndexWriter对象 IndexWriter indexWriter=new IndexWriter(directory,new IndexWriterConfig(new IKAnalyzer())); //步骤三:读取磁盘中文件,对应每一个文件创建一个文档对象 File file=new File("E:\\accp\\Y2\\进阶内容\\Lucene\\资料\\searchsource"); //步骤四:获取文件列表 File[] files=file.listFiles(); for (File item :files) { //步骤五:获取文件数据,封装域 参数三:是否存储 Field fieldName=new TextField("fieldName",item.getName(), Field.Store.YES); Field fieldPath=new StoredField("fieldPath",item.getPath()); Field fieldSize=new LongPoint("fieldSize", FileUtils.sizeOf(item)); Field fieldSizeStore=new StoredField("fieldSize", FileUtils.sizeOf(item)); Field fieldContent=new TextField("fieldContent", FileUtils.readFileToString(item,"UTF-8"), Field.Store.YES); //步骤六:创建文档对象,向文档对象中添加域 Document document=new Document(); document.add(fieldName); document.add(fieldPath); document.add(fieldSize); document.add(fieldContent); document.add(fieldSizeStore); //步骤七:创建索引,将文档对象写入到索引库 indexWriter.addDocument(document); } System.out.println("文档对象写入索引库成功啦!!"); //步骤八:关闭资源 indexWriter.close(); } }
原文:https://www.cnblogs.com/Zzzzn/p/12361879.html