Jforum中索引模块的分析(1)

 较早的时候分析过Jforum中的lucene索引模块,当时觉得代码真是短小精悍!值得学习。

1.SearchManager接口,

  JForum定义了一个SearchManager接口,通过LuceneManager实现了其中的方法。对于索引和检索进行统一的管理。

public class LuceneManager implements SearchManager { private LuceneSearch search; private LuceneSettings settings; private LuceneIndexer indexer; /** * @see net.jforum.search.SearchManager#init() */ public void init() { try { /*读取配置文件,初始化解析器*/ Analyzer analyzer = (Analyzer)Class.forName(SystemGlobals.getValue( ConfigKeys.LUCENE_ANALYZER)).newInstance(); this.settings = new LuceneSettings(analyzer); /*设定索引存放的目录*/ this.settings.useFSDirectory(SystemGlobals.getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH)); this.removeLockFile(); this.indexer = new LuceneIndexer(this.settings); this.search = new LuceneSearch(this.settings, new LuceneContentCollector(this.settings)); /*将LuceneSearch对象作为参数传入,当新的POST提交以后, *建立索引,LuceneSearch关闭索引文件,然后重新打开。*/ this.indexer.watchNewDocuDocumentAdded(this.search); SystemGlobals.setObjectValue(ConfigKeys.LUCENE_SETTINGS, this.settings); } catch (Exception e) { throw new ForumException(e); } }

其余的是,针对POST的create、delete、update索引方法。

2.LuceneIndexer类

   主要是对POST建立索引,主要方法有:

   2.1 create(Post post)

  public void create(Post post) { synchronized (MUTEX) { IndexWriter writer = null; try { writer = new IndexWriter(this.settings.directory(), this.settings.analyzer()); Document document = this.createDocument(post); writer.addDocument(document); this.optimize(writer); if (logger.isDebugEnabled()) { logger.debug("Indexed " + document); } } catch (Exception e) { logger.error(e.toString(), e); } finally { if (writer != null) { try { writer.flush(); writer.close(); this.notifyNewDocumentAdded(); } catch (Exception e) {} } } } } 

  新建一个Lucene中的IndexWriter,通过createDocument方法对于POST进行索引,关闭writer,调用notifyNewDocumentAdded()方法

告知IndexSearch索引已经更新,需要重新的打开。

  2.2 createDocument(Post)方法

  new Field(SearchFields.Keyword.USER_ID, String.valueOf(p.getUserId()), Store.YES, Index.UN_TOKENIZED)); d.add(new Field(SearchFields.Keyword.DATE, this.settings.formatDateTime(p.getTime()), Store.YES, Index.UN_TOKENIZED)); // We add the subject and message text together because, when searching, we only care about the // matches, not where it was performed. The real subject and contents will be fetched from the database d.add(new Field(SearchFields.Indexed.CONTENTS, p.getSubject() + " " + p.getText(), Store.NO, Index.TOKENIZED)); return d; } 

  将POST_ID,FORUM_ID,TOPIC_ID,USER_ID,文章内容进行索引。

  2.3 Update(Post)方法

  更新Post之后,重新建立索引。

  public void update(Post post) { if (this.performDelete(post)) { this.create(post); } } private boolean performDelete(Post p) { synchronized (MUTEX) { IndexReader reader = null; boolean status = false; try { reader = IndexReader.open(this.settings.directory()); reader.deleteDocuments(new Term(SearchFields.Keyword.POST_ID, String.valueOf(p.getId()))); status = true; } catch (IOException e) { logger.error(e.toString(), e); } finally { if (reader != null) { try { reader.close(); } catch (Exception e) {} } } return status; } } 

  首先删除该Post的索引,通过POST_ID,然后重新建立索引。

  2.4 notifyNewDocumentAdded方法

  在建立索引或者重新建立索引之后,都调用notifyNewDocumentAdded通知IndexSearch,索引文件已经更新,需要重新载入。

 

 private void notifyNewDocumentAdded() { for (Iterator iter = this.newDocumentAddedList.iterator(); iter.hasNext(); ) { ((NewDocumentAdded)iter.next()).newDocumentAdded(); } }

 其中LuceneSearch实现了NewDocumentAdded接口。

 <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} --> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

 public void newDocumentAdded() { try { this.search.close(); this.openSearch(); } catch (Exception e) { throw new SearchException(e); } } 

 重新打开索引文件。

3.索引总结

  结构很清晰,就是提交POST或者更新POST之后,重新打开索引文件。

你可能感兴趣的:(Jforum中索引模块的分析(1))