Lucene快速入门(二)_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4165 | 回复: 0   主题: Lucene快速入门(二)        下一篇 
tk
注册用户
等级:中士
经验:207
发帖:80
精华:0
注册:2011-10-19
状态:离线
发送短消息息给tk 加好友    发送短消息息给tk 发消息
发表于: IP:您无权察看 2011-10-19 16:32:55 | [全部帖] [楼主帖] 楼主

三、lucene入门实例:搜索索引

搜索索引作为Lucene两大基本操作之一,涉及到很多具体的搜索设置,这里先用一个简单的搜索实例来展示lucene的搜索功能,代码如下:

Java代码

  1. publicvoid query() throws ParseException, CorruptIndexException, IOException { 
  2.        String queryStr = "lucene"; // 要查询的文本 
  3.       // 1.把查询文本解析成Query对象 
  4.  String[] fields = { "fileName", "fileContent" }; 
  5.        QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_30, fields, analyzer); 
  6.        Query query = queryParser.parse(queryStr); 
  7.        System.out.println("Query对象格式:" + query); 
  8.       // 2.开始查询 
  9.       long start = System.currentTimeMillis(); 
  10.        IndexSearcher searcher = new IndexSearcher(FSDirectory.open(new File(indexDir))); 
  11.        TopDocs topDocs = searcher.search(query, 10000); 
  12.        System.out.println("共计查询到:" + topDocs.totalHits + " 条结果,用时" + (System.currentTimeMillis() - start)+ "毫秒"); 
  13.       for (ScoreDoc scoreDoc : topDocs.scoreDocs) {// 打印查询结果 
  14.             int docSN = scoreDoc.doc; // 文档内部编号 
  15.              Document doc = searcher.doc(docSN); // 根据文档内部编号取出文档 
  16.              System.out.println("fileName=" + doc.get("fileName") + "\t fileSize=" + doc.get("fileSize")+ "\t fileContent=" +doc.get("fileContent") + "\t filePath=" + doc.get("filePath")); 
  17.        } 



简析:IndexSearcher作用就是完成对索引的搜索,但是搜索前必须传递一个Query对象。为什么要传递Query对象而不是传递一个字串直接进行搜索,首先要明确lucene创建索引中用到了字段域,其次要明确一份文档可能有很多字段域组成,搜索时不可能对每个字段域都进行搜索,最后要明确Query对象实质就是字段域信息(打印Query对象可以看出),即是说把搜索字串和字段域的名称相结合构造了字段域。明确了以上三点就不难理解Query对象的创建。搜索结果集TopDocs对象,此对象持有两个重要信息:一是查询到的总记录数,二是查询到记录数的集合(Document对象的集合),类似于数据库查询结果的封装。需要特别说明的是ScoreDoc对象并不是一个真正Document对象,它只是记录了文档对象的编号,要想获取Document对象,还需使用IndexSearcher类的doc方法来查出对应的Document对象。得到了Document对象,就可以获取字段域及查询到的信息。

总结查询三个关键对象:Query对象、IndexWriter对象、TopDocs对象

四、分词器

1.词的定义

词是经过分词器处理后的字串,更具体地说词是经过分词器以下四大操作而形成的字串:

(1)关键词切分:对于英文来说每个单词就是一个关键词,而中文分词会根据一个词典来对关键词进行切分,不同的分词器对词的切分可能不同。

(2)去除停用词:停用词是指一些出现频率较高,但是没有实际意义的词,比如英文中的“a an the”等,中文中的“的了着”等。

(3)词形还原:主要是指把英文中的单词进行去尾操作,如现在分词、过去分词还原成词根形式,复数单词转为单数形式。

(4)转为小写:把所有英文字母全部转成小写字母。

经过以上4步操作后得到的结果称为词元(Token),这些词元共同构成了词。

2.分词结果

为了能看清分词器分词后的效果,我们可以使用如下代码来测试。

Java代码

  1. publicclass AnalyzerTest { 
  2.        String enText = "Look, This's my first test about Lucene,Thanks."; 
  3.        String zhText = "瞧,这是我第一次lucene相关的练习,谢谢。"; 
  4.        String zhText2 = "这是我的第一次关于lucene的练习。"; 
  5.        Analyzer an = new StandardAnalyzer(Version.LUCENE_30); 
  6.       Analyzer an2 = new CJKAnalyzer(Version.LUCENE_30); 
  7.       // 二分法分词器:如“大家好啊”分词结果为:大家、家好、好啊 
  8.       Analyzer an3 = new IKAnalyzer(); 
  9.       // IK分词器作者JE博客地址:linliangyi2007.iteye.com 
  10.       
  11.       @Test
  12.       publicvoid testAnaly() throws IOException { 
  13.              printAnalyzerResult(an, enText); 
  14.              printAnalyzerResult(an2, zhText); 
  15.              printAnalyzerResult(an3, zhText); 
  16.              printAnalyzerResult(an3, zhText2); 
  17.        } 
  18.       
  19.       publicvoid printAnalyzerResult(Analyzer analyzer, String text) throws IOException { 
  20.             System.out.println("分词器:" + analyzer.getClass().getName()); 
  21.              Reader reader = new StringReader(text); 
  22.              TokenStream ts = analyzer.tokenStream("result", reader); 
  23.             while (ts.incrementToken()) { 
  24.                    System.out.println("词元信息:"+ts); 
  25.              } 
  26.        } 



简析:TokenStream是词元的集合(A TokenStream enumerates the sequence of tokens),即是说它包含分词后的所有结果词元。我们也可根据TokenStream来构建一个字段域Field对象,如:Field field = new Field("result",ts); 从分词结果中打印的词元信息我们可以验证“分词器对词进行的四大操作”。

3.由分词引发的问题

(1)使用相同分词器:创建索引时使用的分词器要和搜索时构建Query对象使用分词器相同。(2)在查询时英文字母还原为小写,这一步通常我们不需要关注,因为再把把查询文本解析成Query对象时,分词器会帮我们完成。(3)分词器的选择应以业务而定,也可以根据业务来实现特定的分词器。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论