你好,游客 登录 注册 搜索
背景:
阅读新闻

基于Lucene多索引进行索引和搜索

[日期:2012-05-05] 来源:Linux社区  作者:shirdrn [字体: ]

另外需要说明一点,有关索引数据分布和更新的问题。基于上述随机选择索引目录,在一定程度上能够均匀地将数据分布到不同的目录中,但是在更新的时候,如果处理不当会造成数据的重复(因为随机),解决重复的方法就是在外部增加重复检测工作,限制将重复(非常相似)的文档再次进行索引。

下面我们看一下索引的测试用例,代码如下所示:

  1. package org.shirdrn.lucene;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import junit.framework.TestCase;  
  7.   
  8. import org.apache.lucene.analysis.Analyzer;  
  9. import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;  
  10. import org.apache.lucene.index.IndexWriterConfig;  
  11. import org.apache.lucene.index.IndexWriterConfig.OpenMode;  
  12. import org.apache.lucene.util.Version;  
  13. import org.shirdrn.lucene.MultipleIndexing.MongoConfig;  
  14.   
  15. public class TestMultipleIndexing extends TestCase {  
  16.   
  17.     MultipleIndexing indexer;  
  18.       
  19.     @Override  
  20.     protected void setUp() throws Exception {  
  21.         MongoConfig mongoConfig = new MongoConfig("192.168.0.184"27017"page""Article");  
  22.         String indexRoot = "E:\\Store\\indexes";  
  23.         int maxIndexCommitCount = 200;  
  24.         Analyzer a = new SmartChineseAnalyzer(Version.LUCENE_35, true);  
  25.         IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_35, a);  
  26.         indexConfig.setOpenMode(OpenMode.CREATE);  
  27.         indexer = new MultipleIndexing(indexRoot, maxIndexCommitCount, mongoConfig, indexConfig);  
  28.     }  
  29.       
  30.     @Override  
  31.     protected void tearDown() throws Exception {  
  32.         super.tearDown();  
  33.     }  
  34.       
  35.     public void testIndexing() {  
  36.         Map<String, Object> conditions = new HashMap<String, Object>();  
  37.         conditions.put("spiderName""sinaSpider");  
  38.         indexer.index(conditions);  
  39.     }  
  40. }  
我这里,索引了9w多篇文档,生成的索引还算均匀地分布在名称为a~z的26个目录中。

搜索实现


在搜索的时候,你可以选择ParallelMultiSearcher或MultiSearcher的任意一个,MultiSearcher是在搜索时候,通过一个循环来遍历多个索引获取到检索结果,而ParallelMultiSearcher则是启动多个线程并行执行搜索,使用它们的效率在不同配置的机器上效果是不同的,在实际使用的时候根据你的需要来决定。我简单地使用了MultiSearcher来构建搜索,实现代码如下所示:

  1. package org.shirdrn.lucene;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.lucene.analysis.Analyzer;  
  6. import org.apache.lucene.index.CorruptIndexException;  
  7. import org.apache.lucene.index.IndexWriterConfig;  
  8. import org.apache.lucene.queryParser.ParseException;  
  9. import org.apache.lucene.queryParser.QueryParser;  
  10. import org.apache.lucene.search.MultiSearcher;  
  11. import org.apache.lucene.search.Query;  
  12. import org.apache.lucene.search.ScoreDoc;  
  13. import org.apache.lucene.search.Searcher;  
  14. import org.apache.lucene.search.TopScoreDocCollector;  
  15. import org.apache.lucene.util.Version;  
  16. import org.shirdrn.lucene.IndexHelper.SearcherHelper;  
  17. import org.slf4j.Logger;  
  18. import org.slf4j.LoggerFactory;  
  19.   
  20. /** 
  21.  * Searching accross multiple Lucene indexes. 
  22.  *  
  23.  * @author shirdrn 
  24.  * @date   2011-12-12 
  25.  */  
  26. public class MultipleSearching {  
  27.   
  28.     private static Logger LOG = LoggerFactory.getLogger(MultipleSearching.class);  
  29.     private SearcherHelper searcherHelper;  
  30.     private Searcher searcher;  
  31.     private QueryParser queryParser;  
  32.     private IndexWriterConfig indexConfig;  
  33.       
  34.     private Query query;  
  35.     private ScoreDoc[] scoreDocs;  
  36.       
  37.     public MultipleSearching(String indexRoot, IndexWriterConfig indexConfig) {  
  38.         searcherHelper = IndexHelper.newSearcherHelper(indexRoot, indexConfig);  
  39.         this.indexConfig = indexConfig;  
  40.         try {  
  41.             searcher = new MultiSearcher(searcherHelper.getSearchers());  
  42.             searcher.setSimilarity(indexConfig.getSimilarity());  
  43.             queryParser = new QueryParser(Version.LUCENE_35, "content", indexConfig.getAnalyzer());  
  44.         } catch (IOException e) {  
  45.             e.printStackTrace();  
  46.         }  
  47.     }  
  48.       
  49.     public void search(String queries) {  
  50.         try {  
  51.             query = queryParser.parse(queries);  
  52.             TopScoreDocCollector collector = TopScoreDocCollector.create(100000true);  
  53.             searcher.search(query, collector);  
  54.             scoreDocs = collector.topDocs().scoreDocs;  
  55.         } catch (ParseException e) {  
  56.             e.printStackTrace();  
  57.         } catch (IOException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61.       
  62.     public void iterateDocs(int start, int end) {  
  63.         for (int i = start; i < Math.min(scoreDocs.length, end); i++) {  
  64.             try {  
  65.                 LOG.info(searcher.doc(scoreDocs[i].doc).toString());  
  66.             } catch (CorruptIndexException e) {  
  67.                 e.printStackTrace();  
  68.             } catch (IOException e) {  
  69.                 e.printStackTrace();  
  70.             }  
  71.         }  
  72.     }  
  73.       
  74.     public void explain(int start, int end) {  
  75.         for (int i = start; i < Math.min(scoreDocs.length, end); i++) {  
  76.             try {  
  77.                 System.out.println(searcher.explain(query, scoreDocs[i].doc));  
  78.             } catch (CorruptIndexException e) {  
  79.                 e.printStackTrace();  
  80.             } catch (IOException e) {  
  81.                 e.printStackTrace();  
  82.             }  
  83.         }  
  84.     }  
  85.       
  86.     public void close() {  
  87.         searcherHelper.closeAll();  
  88.         try {  
  89.             searcher.close();  
  90.         } catch (IOException e) {  
  91.             e.printStackTrace();  
  92.         }  
  93.     }  
  94. }  
我们的一个目的是查看搜索是否是在多个索引目录上进行检索,并且最终相关度排序是基于多个索引计算的。上面给出了一个更接近测试用例的实现,iterateDocs()迭代出文档并输出,explain()方法查看得分计算明细。
下面给出搜索的测试用例,代码如下所示:
  1. package org.shirdrn.lucene;  
  2.   
  3. import org.apache.lucene.analysis.Analyzer;  
  4. import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;  
  5. import org.apache.lucene.index.IndexWriterConfig;  
  6. import org.apache.lucene.util.Version;  
  7.   
  8. import junit.framework.TestCase;  
  9.   
  10. public class TestMultipleSearching extends TestCase {  
  11.   
  12.     MultipleSearching searcher;  
  13.       
  14.     @Override  
  15.     protected void setUp() throws Exception {  
  16.         String indexRoot = "E:\\Store\\indexes";  
  17.         Analyzer a = new SmartChineseAnalyzer(Version.LUCENE_35, true);  
  18.         IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_35, a);  
  19.         searcher = new MultipleSearching(indexRoot, indexConfig);  
  20.     }  
  21.       
  22.     @Override  
  23.     protected void tearDown() throws Exception {  
  24.         searcher.close();  
  25.     }  
  26.       
  27.     public void testSearching() {  
  28.         searcher.search("+title:拉斯维加斯^1.25 (+content:美国^1.50 +content:拉斯维加斯)");  
  29.         searcher.iterateDocs(010);  
  30.         searcher.explain(05);  
  31.     }  
  32. }  
linux
相关资讯       Lucene 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款