用户名: 密 码:
您现在的位置:首页 >> SEO技巧 >> 内容

Lucene 2.9.0 的简单实用方法

时间:2009/11/13 10:41:35 点击:4295

  核心提示:先建立索引Java代码 importjava.io.File; importjava.io.FileFilter; importjava.io.FileReader; importjava.io.IOException; importjava.io.Reader; importjava.util.H...

先建立索引

Java代码
  1. import java.io.File;   
  2. import java.io.FileFilter;   
  3. import java.io.FileReader;   
  4. import java.io.IOException;   
  5. import java.io.Reader;   
  6. import java.util.HashSet;   
  7. import java.util.Set;   
  8. import org.apache.commons.logging.Log;   
  9. import org.apache.commons.logging.LogFactory;   
  10. import org.apache.lucene.analysis.Analyzer;   
  11. import org.apache.lucene.document.Document;   
  12. import org.apache.lucene.document.Field;   
  13. import org.apache.lucene.index.CorruptIndexException;   
  14. import org.apache.lucene.index.IndexReader;   
  15. import org.apache.lucene.index.IndexWriter;   
  16. import org.apache.lucene.store.FSDirectory;   
  17. import org.apache.lucene.store.LockObtainFailedException;   
  18. import org.wltea.analyzer.lucene.IKAnalyzer;   
  19. import vrvclient.util.ConfigUtil;   
  20. import vrvclient.util.FileListUtil;   
  21.   
  22. /**  
  23.  *  
  24.  * @author lan  
  25.  */  
  26. public class Indexer extends Constants {   
  27.   
  28.     private static final Log log = LogFactory.getLog(Indexer.class);   
  29.   
  30.     public void index(File[] files, FileFilter filter) {   
  31.         if (files == null) {   
  32.             return;   
  33.         }   
  34. //        System.out.println(filter.getClass());   
  35.         Set<File> set = new HashSet<File>();   
  36.         for (File f : files) {//过滤掉不合要求的文件,如后缀,文件名等   
  37.             FileListUtil.list(f, filter, set);   
  38.         }   
  39.         File indexDir = new File(ConfigUtil.getIndexPath());//这里是获得索引文件的保存路径的   
  40.         Analyzer analyzer = new IKAnalyzer();//使用国产的IK分词器,很好很强大   
  41.         try {   
  42.             FSDirectory dir = FSDirectory.open(indexDir);//保存到硬盘上   
  43.             IndexWriter iw = new IndexWriter(dir, analyzer, !IndexReader.indexExists(dir), IndexWriter.MaxFieldLength.LIMITED);   
  44.             for (File f : set) {   
  45.                 if (f.isFile()) {   
  46. //                    System.out.println(f.getAbsolutePath());   
  47.                     Document doc = new Document();   
  48.                     Reader reader = new FileReader(f);   
  49.                     doc.add(new Field(PATH, f.getAbsolutePath(), Field.Store.YES, Field.Index.ANALYZED));//保存路径   
  50.                     doc.add(new Field(FILE, reader));//保存文件   
  51.                     iw.addDocument(doc);   
  52.                     reader.close();   
  53.                 }   
  54.             }   
  55.             iw.optimize();   
  56.             iw.close();   
  57.         } catch (CorruptIndexException ex) {   
  58.             log.error(ex.getMessage(), ex);   
  59.         } catch (LockObtainFailedException ex) {   
  60.             log.error(ex.getMessage(), ex);   
  61.         } catch (IOException ex) {   
  62.             log.error(ex.getMessage(), ex);   
  63.         }   
  64.     }   
  65. }  
 

这个是搜索结果

Java代码 复制代码
  1. import java.io.File;   
  2. import java.io.IOException;   
  3. import java.util.HashSet;   
  4. import java.util.Set;   
  5. import org.apache.commons.logging.Log;   
  6. import org.apache.commons.logging.LogFactory;   
  7. import org.apache.lucene.analysis.Analyzer;   
  8. import org.apache.lucene.document.Document;   
  9. import org.apache.lucene.queryParser.ParseException;   
  10. import org.apache.lucene.queryParser.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.FSDirectory;   
  16. import org.wltea.analyzer.lucene.IKAnalyzer;   
  17. import vrvclient.util.ConfigUtil;   
  18.   
  19. /**  
  20.  *  
  21.  * @author lan  
  22.  */  
  23. public class Searcher extends Constants {   
  24.   
  25.     private static final Log log = LogFactory.getLog(Indexer.class);   
  26.   
  27.     /**  
  28.      *  
  29.      * @param contents  
  30.      * @param combineMode true = and,false = or  
  31.      * @param limit -1=all  
  32.      */  
  33.     public Set<String> search(String[] contents, boolean combineMode, int limit) {   
  34.         Set<String> paths = new HashSet<String>();   
  35.         try {   
  36.             File indexDir = new File(ConfigUtil.getIndexPath());   
  37.             FSDirectory fsd = FSDirectory.open(indexDir);   
  38.             IndexSearcher is = new IndexSearcher(fsd, true);   
  39.             Analyzer analyzer = new IKAnalyzer();   
  40.             if (fsd.getFile().exists()) {   
  41.                 QueryParser qp = new QueryParser(FILE, analyzer);   
  42.                 StringBuilder sb = new StringBuilder();   
  43.                 String jioner = "";   
  44.                 if (combineMode) {//如果是and,则所有条件要同时满足   
  45.                     jioner = "+";   
  46.                 }   
  47.                 boolean b = true;   
  48.                 for (String s : contents) {   
  49.                     s = s.replaceAll("\\s+"" AND ");//防止条件中的空格被看成“或”,把其变成“与”   
  50.                     if (!b) {   
  51.                         sb.append(" ");   
  52.                     }   
  53.                     sb.append(jioner).append("(").append(s).append(")");   
  54.                     b = false;   
  55.                 }   
  56.                 Query q = qp.parse(sb.toString());   
  57.                 log.info(q.toString());   
  58.                 if (limit == -1) {   
  59.                     limit = is.maxDoc();   
  60.                 }   
  61.   
  62.                 TopDocs hits = is.search(q, limit);   
  63.                 ScoreDoc[] sds = hits.scoreDocs;   
  64.                 for (int i = 0; i < sds.length; i++) {   
  65.                     ScoreDoc sd = sds[i];   
  66.                     Document doc = is.doc(sd.doc);   
  67. //                    System.out.println("Hit:(" + sd.score + ")" + doc.toString());   
  68. //本来想同时得到命中次数,也就是词频,但是网上找到的都是老版本的,这里不能用。   
  69.                     paths.add(doc.get(PATH));//返回匹配的路径   
  70.                 }   
  71.             }   
  72.             is.close();   
  73.         } catch (ParseException ex) {   
  74.             log.error(ex.getMessage(), ex);   
  75.         } catch (IOException ex) {   
  76.             log.error(ex.getMessage(), ex);   
  77.         }   
  78.         return paths;   
  79.     }   
  80. }  

 

附用到的工具类:

Java代码 复制代码
  1. import java.io.File;   
  2. import java.io.FileFilter;   
  3. import java.util.Map;   
  4. import java.util.Set;   
  5.   
  6. /**  
  7.  *  
  8.  * @author lan  
  9.  */  
  10. public final class FileListUtil {   
  11.   
  12. //返回一定数量的符合要求的文件   
  13.     public static void list(File f, FileFilter filter, Set<File> set, int limit) {   
  14.         if (limit > -1 && set.size() >= limit) {   
  15.             return;   
  16.         }   
  17.         if (f == null) {   
  18.             return;   
  19.         }   
  20.         if (f.isFile()) {   
  21.             set.add(f);   
  22.         } else if (f.isDirectory()) {   
  23.             File[] files = null;   
  24.             if (filter == null) {   
  25.                 files = f.listFiles();   
  26.             } else {   
  27.                 files = f.listFiles(filter);   
  28.             }   
  29.             if (files != null) {   
  30.                 for (File file : files) {   
  31.                     list(file, filter, set, limit);   
  32.                 }   
  33.             }   
  34.         }   
  35.     }   
  36.   
  37. //返回所有的符合要求的文件,不要担心set放不上,至少我的D盘资料盘都放进去都没有内存溢出   
  38.     public static void list(File f, FileFilter filter, Set<File> set) {   
  39.         if (f == null) {   
  40.             return;   
  41.         }   
  42.         if (f.isFile()) {   
  43.             set.add(f);   
  44.         } else if (f.isDirectory()) {   
  45.             File[] files = null;   
  46.             if (filter == null) {   
  47.                 files = f.listFiles();   
  48.             } else {   
  49.                 files = f.listFiles(filter);   
  50.             }   
  51.             if (files != null) {   
  52.                 for (File file : files) {   
  53.                     list(file, filter, set);   
  54.                 }   
  55.             }   
  56.         }   
  57.     }   
  58.   
  59. //其实是打包工具类用到的   
  60.     public static void list(File f, FileFilter filter, String parent, Map<String, File> map) {   
  61.         if (f == null) {   
  62.             return;   
  63.         }   
  64.         String name = f.getName();   
  65.         if (parent != null) {   
  66.             name = parent + "/" + name;   
  67.         }   
  68.         if (f.isFile()) {   
  69.             map.put(name, f);   
  70.         } else if (f.isDirectory()) {   
  71.             File[] files = null;   
  72.             if (filter == null) {   
  73.                 files = f.listFiles();   
  74.             } else {   
  75.                 files = f.listFiles(filter);   
  76.             }   
  77.             if (files != null) {   
  78.                 for (File file : files) {   
  79.                     list(file, filter, name, map);   
  80.                 }   
  81.             }   
  82.         }   
  83.     }   
  84. }  

 

常量类,大部分人用接口,但是我不太喜欢用接口来保存常量,虽然更方便点,但是不合规范。

Java代码
  1. public class Constants {//可以替换成枚举,没必要了   
  2.   
  3.     protected static final String PATH = "path";   
  4.     protected static final String FILE = "file";   
  5. }  

文章来源:http://www.xinxilong.com

作者:不详 来源:网络
相关评论
发表我的评论
  • 大名:
  • 内容:
  • 论坛群发大师(www.xinxilong.com) © 2008 版权所有 All Rights Resverved.
  • Email:4984672[at]qq.com 沪ICP备12025887号-1
  • Powered by 论坛群发大师