lucene3.0 中文分词实例IKAnalyzer StandardAnalyzer

之前想做lucene的中文分词,上网一搜,结果都是针对lucene2.x的,于是就写了一实例针对lucene3.x版本的,以下仅为学习交流之用;

时间仓促,实例示下:


package com.hpjianhua.lucene;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

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.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
* 分词器测试类,支持lucene3.0以上版本
* 分词器IKAnalyzer3.2.5Stable.jar
* @author hpjianhua
* @Date 2011 04 08
*
*/
public class TokenTest {

// 要分词的字符串
private static String text = "中国,古时通常泛指中原地区,与中华中夏 中土中州含义相同。古代华夏族、汉族建国于黄河流域一带,以为居天下之中,故称中国";
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Analyzer ikAnalyzer = new IKAnalyzer();
System.out.println("======中文=======IKAnalyzer======分词=======");
showToken(ikAnalyzer, text);

Analyzer standardAnalyzer = new StandardAnalyzer(Version.LUCENE_30);
System.out.println("=====一元========StandardAnalyzer=====分词========");
showToken(standardAnalyzer, text);
}

/**
* 分词及打印分词结果的方法
* @param analyzer 分词器名称
* @param text 要分词的字符串
* @throws IOException 抛出的异常
*/
public static void showToken(Analyzer analyzer, String text) throws IOException {

Reader reader = new StringReader(text);
TokenStream stream = (TokenStream)analyzer.tokenStream("", reader);
//添加工具类 注意:以下这些与之前lucene2.x版本不同的地方
TermAttribute termAtt = (TermAttribute)stream.addAttribute(TermAttribute.class);
OffsetAttribute offAtt = (OffsetAttribute)stream.addAttribute(OffsetAttribute.class);
// 循环打印出分词的结果,及分词出现的位置
while(stream.incrementToken()){
System.out.print(termAtt.term() + "|("+ offAtt.startOffset() + " " + offAtt.endOffset()+")");
}
System.out.println();
}

}




输出结果如下:


======中文=======IKAnalyzer======分词=======
中国|(0 2)古时|(3 5)通常|(5 7)泛指|(7 9)中原地区|(9 13)中原|(9 11)原地区|(10 13)原地|(10 12)地区|(11 13)与|(14 15)中华|(15 17)华中|(16 18)中夏|(17 19)中土|(20 22)中州|(22 24)含义|(24 26)相同|(26 28)古代|(29 31)华夏|(31 33)夏|(32 33)族|(33 34)汉族|(35 37)建国|(37 39)于|(39 40)黄河流域|(40 44)黄河|(40 42)河流|(41 43)流域|(42 44)一带|(44 46)一|(44 45)以为|(47 49)居|(49 50)天下|(50 52)之中|(52 54)故|(55 56)称|(56 57)中国|(57 59)
=====一元========StandardAnalyzer=====分词========
中|(0 1)国|(1 2)古|(3 4)时|(4 5)通|(5 6)常|(6 7)泛|(7 8)指|(8 9)中|(9 10)原|(10 11)地|(11 12)区|(12 13)与|(14 15)中|(15 16)华|(16 17)中|(17 18)夏|(18 19)中|(20 21)土|(21 22)中|(22 23)州|(23 24)含|(24 25)义|(25 26)相|(26 27)同|(27 28)古|(29 30)代|(30 31)华|(31 32)夏|(32 33)族|(33 34)汉|(35 36)族|(36 37)建|(37 38)国|(38 39)于|(39 40)黄|(40 41)河|(41 42)流|(42 43)域|(43 44)一|(44 45)带|(45 46)以|(47 48)为|(48 49)居|(49 50)天|(50 51)下|(51 52)之|(52 53)中|(53 54)故|(55 56)称|(56 57)中|(57 58)国|(58 59)

示例代码: //src要创建索引的文件,destDir索引存放的目录 public static void createIndex(File src, File destDir){ Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); //创建一个语法分析器 IndexWriter iwriter = null; Directory directory = null; try { directory = FSDirectory.open(destDir); //把索引文件存储到磁盘目录 //创建一个IndexWriter(存放索引文件的目录,分析器,Field的最大长度) iwriter = new IndexWriter(directory, analyzer,true, IndexWriter.MaxFieldLength.UNLIMITED); //iwriter.setUseCompoundFile(true);//使用复合文件 Document doc = new Document(); //创建一个Document对象 //把文件路径作为"path"域:不分词,索引,保存 doc.add(new Field("path", src.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED)); StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new FileReader(src)); for(String str = null; (str = br.readLine())!=null;){ sb.append(str).append(System.getProperty("line.separator")); } //文件内容作为"content"域:分词,索引,保存 doc.add(new Field("contents", sb.toString(), Field.Store.YES, Field.Index.ANALYZED)); iwriter.addDocument(doc); //把Document存放到IndexWriter中 iwriter.optimize(); //对索引进行优化 } catch (IOException e) { e.printStackTrace(); } finally { if (iwriter != null) { try { iwriter.close(); //关闭IndexWriter时,才把内存中的数据写到文件 } catch (IOException e) { e.printStackTrace(); } } if (directory != null) { try { directory.close(); //关闭索引存放目录 } catch (IOException e) { e.printStackTrace(); } } } } //src要创建索引的文件,destDir索引存放的目录 public static void createIndex(File src, File destDir){ Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); //创建一个语法分析器 IndexWriter iwriter = null; Directory directory = null; try { directory = FSDirectory.open(destDir); //把索引文件存储到磁盘目录 //创建一个IndexWriter(存放索引文件的目录,分析器,Field的最大长度) iwriter = new IndexWriter(directory, analyzer,true, IndexWriter.MaxFieldLength.UNLIMITED); //iwriter.setUseCompoundFile(true);//使用复合文件 Document doc = new Document(); //创建一个Document对象 //把文件路径作为"path"域:不分词,索引,保存 doc.add(new Field("path", src.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED)); StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new FileReader(src)); for(String str = null; (str = br.readLine())!=null;){ sb.append(str).append(System.getProperty("line.separator")); } //文件内容作为"content"域:分词,索引,保存 doc.add(new Field("contents", sb.toString(), Field.Store.YES, Field.Index.ANALYZED)); iwriter.addDocument(doc); //把Document存放到IndexWriter中 iwriter.optimize(); //对索引进行优化 } catch (IOException e) { e.printStackTrace(); } finally { if (iwriter != null) { try { iwriter.close(); //关闭IndexWriter时,才把内存中的数据写到文件 } catch (IOException e) { e.printStackTrace(); } } if (directory != null) { try { directory.close(); //关闭索引存放目录 } catch (IOException e) { e.printStackTrace(); } } } } 6. 查询索引 1) IndexSearcher: 索引查询器 a) 构造器: IndexSearcher(Directory path, boolean readOnly) b) 常用方法: TopDocs search(Query query, Filter filter, int n); //执行查询。n指的是最多返回的Document的数量。 Document doc(int 文件内部编号); //根据文档的内部编号获取到该Document void close(); //关闭查询器 2) Query: 查询对象。把用户输入的查询字符串封装成Lucene能够识别的Query对象。 3) Filter: 用来过虑搜索结果的对象。 4) TopDocs: 代表查询结果集信息对象。它有两个属性: a) totalHits: 查询命中数。 b) scoreDocs: 查询结果信息。它包含符合条件的Document的内部编号(doc)及评分(score)。 5) 示例代码: //keyword要搜索的关键字。indexDir索引存放的目录 public static void searcher(String keyword, File indexDir){ IndexSearcher isearcher = null; Directory directory = null; try{ Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); directory = FSDirectory.open(indexDir); //创建解析器 QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "contents", analyzer); Query query = parser.parse(keyword);//获取查询对象 // Query query1 = new TermQuery(new Term("contents", keyword)); // Query query2 = new TermQuery(new Term("contents", keyword2)); // BooleanQuery query = new BooleanQuery(); // query.add(query1, Occur.SHOULD); // query.add(query2, Occur.SHOULD); // QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, new String[]{"path", "contents"}, analyzer); // Query query = parser.parse(keyword); isearcher = new IndexSearcher(directory, true); //创建索引搜索器 TopDocs ts = isearcher.search(query, null, 100); //执行搜索,获取查询结果集对象 int totalHits = ts.totalHits; //获取命中数 System.out.println("命中数:" + totalHits); ScoreDoc[] hits = ts.scoreDocs; //获取命中的文档信息对象 for (int i = 0; i < hits.length; i++) { Document hitDoc = isearcher.doc(hits[i].doc); //根据命中的文档的内部编号获取该文档 System.out.println(hitDoc.getField("contents").stringValue()); //输出该文档指定域的值 } } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } finally { if (isearcher != null) { try { isearcher.close(); //关闭搜索器 } catch (IOException e) { e.printStackTrace(); } } if (directory != null) { try { directory.close(); //关闭索引存放目录 } catch (IOException e) { e.printStackTrace(); } } } } //keyword要搜索的关键字。indexDir索引存放的目录 public static void searcher(String keyword, File indexDir){ IndexSearcher isearcher = null; Directory directory = null; try{ Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); directory = FSDirectory.open(indexDir); //创建解析器 QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "contents", analyzer); Query query = parser.parse(keyword);//获取查询对象 // Query query1 = new TermQuery(new Term("contents", keyword)); // Query query2 = new TermQuery(new Term("contents", keyword2)); // BooleanQuery query = new BooleanQuery(); // query.add(query1, Occur.SHOULD); // query.add(query2, Occur.SHOULD); // QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, new String[]{"path", "contents"}, analyzer); // Query query = parser.parse(keyword); isearcher = new IndexSearcher(directory, true); //创建索引搜索器 TopDocs ts = isearcher.search(query, null, 100); //执行搜索,获取查询结果集对象 int totalHits = ts.totalHits; //获取命中数 System.out.println("命中数:" + totalHits); ScoreDoc[] hits = ts.scoreDocs; //获取命中的文档信息对象 for (int i = 0; i < hits.length; i++) { Document hitDoc = isearcher.doc(hits[i].doc); //根据命中的文档的内部编号获取该文档 System.out.println(hitDoc.getField("contents").stringValue()); //输出该文档指定域的值 } } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } finally { if (isearcher != null) { try { isearcher.close(); //关闭搜索器 } catch (IOException e) { e.printStackTrace(); } } if (directory != null) { try { directory.close(); //关闭索引存放目录 } catch (IOException e) { e.printStackTrace(); } } } } 7. 删除索引 IndexWriter提供deleteDocuments(Term term); //会删除索引文件里含有指定Term的所有Document。 IndexReader也提供了deleteDocuments(Term term);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值