【Lucene4.8教程之一】使用Lucene4.8进行索引及搜索的基本操作

在Lucene对文本进行处理的过程中,可以大致分为三大部分:

1、索引文件:提取文档内容并分析,生成索引

2、搜索内容:搜索索引内容,根据搜索关键字得出搜索结果

3、分析内容:对搜索词汇进行分析,生成Quey对象。


注:事实上,除了最基本的完全匹配搜索以外,其它都需要在搜索前进行分析。

如不加分析步骤,则搜索JAVA,是没有结果的,因为在索引过程中已经将词汇均转化为小写,而此处搜索时则要求关键字完全匹配。

使用了QueryParser类以后,则根据Analyzer的具体实现类,对搜索词汇进行分析,如大小写转换,java and ant等的搜索词解释等。


一、索引文件

基本步骤如下:

1、创建索引库IndexWriter

2、根据文件创建文档Document

 3、向索引库中写入文档内容

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.ljh.search.index;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileReader;  
  5. import java.io.IOException;  
  6.   
  7. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  8. import org.apache.lucene.document.Document;  
  9. import org.apache.lucene.document.Field;  
  10. import org.apache.lucene.document.LongField;  
  11. import org.apache.lucene.document.StringField;  
  12. import org.apache.lucene.document.TextField;  
  13. import org.apache.lucene.index.IndexWriter;  
  14. import org.apache.lucene.index.IndexWriterConfig;  
  15. import org.apache.lucene.store.Directory;  
  16. import org.apache.lucene.store.FSDirectory;  
  17. import org.apache.lucene.util.Version;  
  18.   
  19. // 1、创建索引库IndexWriter  
  20. // 2、根据文件创建文档Document  
  21. // 3、向索引库中写入文档内容  
  22.   
  23. public class IndexFiles {  
  24.   
  25.     public static void main(String[] args) throws IOException {  
  26.   
  27.         String usage = "java IndexFiles"  
  28.                 + " [-index INDEX_PATH] [-docs DOCS_PATH] \n\n"  
  29.                 + "This indexes the documents in DOCS_PATH, creating a Lucene index"  
  30.                 + "in INDEX_PATH that can be searched with SearchFiles";  
  31.   
  32.         String indexPath = null;  
  33.         String docsPath = null;  
  34.         for (int i = 0; i < args.length; i++) {  
  35.             if ("-index".equals(args[i])) {  
  36.                 indexPath = args[i + 1];  
  37.                 i++;  
  38.             } else if ("-docs".equals(args[i])) {  
  39.                 docsPath = args[i + 1];  
  40.                 i++;  
  41.             }  
  42.         }  
  43.   
  44.         if (docsPath == null) {  
  45.             System.err.println("Usage: " + usage);  
  46.             System.exit(1);  
  47.         }  
  48.   
  49.         final File docDir = new File(docsPath);  
  50.         if (!docDir.exists() || !docDir.canRead()) {  
  51.             System.out  
  52.                     .println("Document directory '"  
  53.                             + docDir.getAbsolutePath()  
  54.                             + "' does not exist or is not readable, please check the path");  
  55.             System.exit(1);  
  56.         }  
  57.   
  58.         IndexWriter writer = null;  
  59.         try {  
  60.             // 1、创建索引库IndexWriter  
  61.             writer = getIndexWriter(indexPath);  
  62.             index(writer, docDir);  
  63.         } catch (IOException e) {  
  64.             e.printStackTrace();  
  65.         } finally {  
  66.             writer.close();  
  67.         }  
  68.   
  69.     }  
  70.   
  71.     private static IndexWriter getIndexWriter(String indexPath)  
  72.             throws IOException {  
  73.   
  74.         Directory indexDir = FSDirectory.open(new File(indexPath));  
  75.   
  76.         IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_48,  
  77.                 new StandardAnalyzer(Version.LUCENE_48));  
  78.   
  79.         IndexWriter writer = new IndexWriter(indexDir, iwc);  
  80.   
  81.         return writer;  
  82.     }  
  83.   
  84.     private static void index(IndexWriter writer, File file) throws IOException {  
  85.   
  86.         if (file.isDirectory()) {  
  87.             String[] files = file.list();  
  88.             if (files != null) {  
  89.                 for (int i = 0; i < files.length; i++) {  
  90.                     index(writer, new File(file, files[i]));  
  91.                 }  
  92.             }  
  93.         } else {  
  94.             // 2、根据文件创建文档Document  
  95.             Document doc = new Document();  
  96.             Field pathField = new StringField("path", file.getPath(),  
  97.                     Field.Store.YES);  
  98.             doc.add(pathField);  
  99.             doc.add(new LongField("modified", file.lastModified(),  
  100.                     Field.Store.NO));  
  101.             doc.add(new TextField("contents"new FileReader(file)));  
  102.             System.out.println("Indexing " + file.getName());  
  103.               
  104.             // 3、向索引库中写入文档内容  
  105.             writer.addDocument(doc);  
  106.         }  
  107.   
  108.     }  
  109.   
  110. }  

(1)使用“java indexfiles -index d:/index -docs d:/tmp”运行程序,索引d:/tmp中的文件,并将索引文件放置到d:/index。

(2)上述生成的索引文件可以使用Luke进行查看。目前Luke已迁移至github进行托管。


二、搜索文件

1、打开索引库IndexSearcher
2、根据关键词进行搜索
3、遍历结果并处理

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.ljh.search.search;  
  2.   
  3. //1、打开索引库IndexSearcher  
  4. //2、根据关键词进行搜索  
  5. //3、遍历结果并处理  
  6. import java.io.File;  
  7. import java.io.IOException;  
  8.   
  9. import org.apache.lucene.index.DirectoryReader;  
  10. import org.apache.lucene.index.IndexReader;  
  11. import org.apache.lucene.index.Term;  
  12. import org.apache.lucene.search.IndexSearcher;  
  13. import org.apache.lucene.search.ScoreDoc;  
  14. import org.apache.lucene.search.TermQuery;  
  15. import org.apache.lucene.search.TopDocs;  
  16. import org.apache.lucene.store.Directory;  
  17. import org.apache.lucene.store.FSDirectory;  
  18.   
  19. public class Searcher {  
  20.     public static void main(String[] args) throws IOException {  
  21.   
  22.         String indexPath = null;  
  23.         String term = null;  
  24.         for (int i = 0; i < args.length; i++) {  
  25.             if ("-index".equals(args[i])) {  
  26.                 indexPath = args[i + 1];  
  27.                 i++;  
  28.             } else if ("-term".equals(args[i])) {  
  29.                 term = args[i + 1];  
  30.                 i++;  
  31.             }  
  32.         }  
  33.   
  34.         System.out.println("Searching " + term + " in " + indexPath);  
  35.   
  36.         // 1、打开索引库  
  37.         Directory indexDir = FSDirectory.open(new File(indexPath));  
  38.         IndexReader ir = DirectoryReader.open(indexDir);  
  39.         IndexSearcher searcher = new IndexSearcher(ir);  
  40.   
  41.         // 2、根据关键词进行搜索  
  42.         TopDocs docs = searcher.search(  
  43.                 new TermQuery(new Term("contents", term)), 20);  
  44.   
  45.         // 3、遍历结果并处理  
  46.         ScoreDoc[] hits = docs.scoreDocs;  
  47.         System.out.println(hits.length);  
  48.         for (ScoreDoc hit : hits) {  
  49.             System.out.println("doc: " + hit.doc + " score: " + hit.score);  
  50.         }  
  51.   
  52.         ir.close();  
  53.   
  54.     }  
  55.   
  56. }  

三、分析

事实上,除了最基本的完全匹配搜索以外,其它都需要在搜索前进行分析。

如不加分析步骤,则搜索JAVA,是没有结果的,因为在索引过程中已经将词汇均转化为小写,而此处搜索时则要求关键字完全匹配。

使用了QueryParser类以后,则根据Analyzer的具体实现类,对搜索词汇进行分析,如大小写转换,java and ant等的搜索词解释等。

分析过程有2个基本步骤:

1、生成QueryParser对象

2、调用QueryParser.parse()生成Query()对象。

具体代码,将下述代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 2、根据关键词进行搜索  
  2. TopDocs docs = searcher.search(  
  3.         new TermQuery(new Term("contents", term)), 20);  
用以下代替:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 2、根据关键词进行搜索  
  2. /*TopDocs docs = searcher.search( 
  3.         new TermQuery(new Term("contents", term)), 10);*/  
  4. QueryParser parser = new QueryParser(Version.LUCENE_48, "contents"new SimpleAnalyzer(Version.LUCENE_48));  
  5. Query query = null;  
  6. try {  
  7.     query = parser.parse(term);  
  8. catch (ParseException e) {  
  9.     e.printStackTrace();  
  10. }  
  11. TopDocs docs = searcher.search(query, 30);  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值