??xml version="1.0" encoding="utf-8" standalone="yes"?>黑人一区二区三区四区五区,岛国在线大片,欧美成人精品一区二区男人小说http://www.aygfsteel.com/rain1102/category/37646.html<br/><font color="green" style="font-family: 华文行楷;font-size:16px;">子曰Q危邦不入,乱邦不居。天下有道则见,无道则隐?lt;/font><font color="#3C1435"></font>zh-cnSun, 09 Aug 2009 17:08:31 GMTSun, 09 Aug 2009 17:08:31 GMT60当前几个主要的Lucene中文分词器的比较【{载?/title><link>http://www.aygfsteel.com/rain1102/archive/2009/08/09/290409.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Sun, 09 Aug 2009 02:15:00 GMT</pubDate><guid>http://www.aygfsteel.com/rain1102/archive/2009/08/09/290409.html</guid><wfw:comment>http://www.aygfsteel.com/rain1102/comments/290409.html</wfw:comment><comments>http://www.aygfsteel.com/rain1102/archive/2009/08/09/290409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/rain1102/comments/commentRss/290409.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/rain1102/services/trackbacks/290409.html</trackback:ping><description><![CDATA[转蝲地址Qhttp://www.javaeye.com/news/9637<br /> <p><strong>1. 基本介绍Q?/strong></p> <p><a target="_blank">paoding</a> QLucene中文分词“庖丁解牛” Paoding Analysis<br /> <a target="_blank">imdict</a> Qimdict词典所采用的智能中文分词程?br /> <a target="_blank">mmseg4j</a> Q??Chih-Hao Tsai ?<a target="_blank">MMSeg 法</a> 实现的中文分词器<br /> <a target="_blank">ik</a> Q采用了Ҏ?#8220;正向q代最l粒度切分算?#8220;Q多子处理器分析模式</p> <p> </p> <p> </p> <p><strong>2. 开发者及开发活跃度Q?/strong></p> <p><a target="_blank">paoding</a> Q?a style="white-space: nowrap" target="_blank">qieqie.wang</a>Q?google code 上最后一ơ代码提交:2008-06-12Qsvn 版本?132<br /> <a target="_blank">imdict</a> Q?a target="_blank">XiaoPingGao</a>Q?q入?lucene contributeQlucene trunk ?contrib/analyzers/smartcn/ 最后一ơ提交:2009-07-24Q?br /> <a target="_blank">mmseg4j</a> Q?a style="white-space: nowrap" target="_blank">chenlb2008</a>Qgoogle code ?2009-08-03 Q昨天)Q版本号 57Qlog为:mmseg4j-1.7 创徏分支<br /> <a target="_blank">ik</a> Q?a style="white-space: nowrap" target="_blank">linliangyi2005</a>Qgoogle code ?2009-07-31Q版本号 41</p> <p> </p> <p> </p> <p><strong>3. 用户自定义词库:</strong></p> <p><a target="_blank">paoding</a> Q支持不限制个数的用戯定义词库Q纯文本格式Q一行一词,使用后台U程词库的更新Q自动编译更新过的词库到二进制版本,q加?br /> <a target="_blank">imdict</a> Q暂时不支持用户自定义词库。但 原版 <a title="中科院中文分词系l? target="_blank">ICTCLAS</a> 支持。支持用戯定义 stop words<br /> <a target="_blank">mmseg4j</a> Q自带sogou词库Q支持名?wordsxxx.dicQ?utf8文本格式的用戯定义词库Q一行一词。不支持自动?-Dmmseg.dic.path<br /> <a target="_blank">ik</a> Q?支持apiU的用户词库加蝲Q和配置U的词库文g指定Q无 BOM ?UTF-8 ~码Q\r\n 分割。不支持自动?/p> <p> </p> <p> </p> <p><strong>4. 速度Q基于官方介l,非自己测试)</strong></p> <p><a target="_blank">paoding</a> Q在PIII 1G内存个h机器上,<strong>1U?/strong> 可准分?<strong>100?/strong> 汉字<br /> <a target="_blank">imdict</a> Q?strong>483.64</strong> (字节/U?Q?strong>259517</strong>(汉字/U?<br /> <a target="_blank">mmseg4j</a> Q?complex 1200kb/s左右, simple 1900kb/s左右<br /> <a target="_blank">ik</a> Q具?0万字/U的高速处理能?/p> <p> </p> <p> </p> <p><strong>5. 法和代码复杂度</strong></p> <p><a target="_blank">paoding</a> Qsvn src 目录一?.3MQ?个properties文gQ?8个java文gQ?895 行。用不用的 Knife 切不同类型的,不算很复杂?br /> <a target="_blank">imdict</a> Q词?6.7MQ这个词库是必须的)Qsrc 目录 152kQ?0个java文gQ?399行。?<a title="中科院中文分词系l? target="_blank">ICTCLAS</a> HHMM隐马科夫模型,“利用大量语料库的训练来统计汉语词汇的词频和蟩转概率,从而根据这些统计结果对整个汉语句子计算最似然(likelihood)的切?#8221;<br /> <a target="_blank">mmseg4j</a> Q?svn src 目录一?132kQ?3个java文gQ?089行?a target="_blank">MMSeg 法</a> Q有点复杂?br /> <a target="_blank">ik</a> Q?svn src 目录一?.6M(词典文g也在里面)Q?2个java文gQ?217行。多子处理器分析Q跟paodingcMQ歧义分析算法还没有弄明白?/p> <p> </p> <p> </p> <p><strong>6. 文档</strong></p> <p><a target="_blank">paoding</a> Q几乎无。代码里有一些注释,但因为实现比较复杂,M码还是有一些难度的?br /> <a target="_blank">imdict</a> Q?几乎无?<a title="中科院中文分词系l? target="_blank">ICTCLAS</a> 也没有详l的文档QHHMM隐马科夫模型的数学性太强,不太好理解?br /> <a target="_blank">mmseg4j</a> Q?<a target="_blank">MMSeg 法</a> 是英文的Q但原理比较单。实C比较清晰?br /> <a target="_blank">ik</a> Q?有一个pdf使用手册Q里面有使用CZ和配|说明?/p> <p> </p> <p> </p> <p><strong>7. 其它</strong></p> <p><a target="_blank">paoding</a> Q引入隐喻,设计比较合理。search 1.0 版本q的这个。主要优势在于原生支持词库更新检。主要劣势ؓ作者已l不更新甚至不维护了?br /> <a target="_blank">imdict</a> Q进入了 lucene trunkQ原?ictclas 在各U评中都有不错的表玎ͼ有坚实的理论基础Q不是个人山寨。缺点ؓ暂时不支持用戯库?br /> <a target="_blank">mmseg4j</a> Q?在complex基础上实C最多分?max-word)Q但是还不成熟,q有很多需要改q的地方?br /> <a target="_blank">ik</a> Q?nbsp; 针对Lucene全文索优化的查询分析器IKQueryParser</p> <p> </p> <p> </p> <p><strong>8. l论</strong></p> <p>个h觉得Q可以在 mmseg4j ?paoding 中选一个。关于这两个分词效果的对比,可以参考:</p> <p><a title="mmseg4j与paoding分词效果比较" target="_blank">http://blog.chenlb.com/2009/04/mmseg4j-max-word-segment-compare-with-paoding-in-effect.html</a></p> <p>或者自己再包装一下,?paoding 的词库更新检做一个单独的模块实现Q然后就可以在所有基于词库的分词法之间无缝切换了?/p> <p> </p> <p> </p> <p><strong>ps</strong>Q对不同?field 使用不同的分词器是一个可以考虑的方法。比?tag 字段Q就应该使用一个最单的分词器,按空格分词就可以了?/p><img src ="http://www.aygfsteel.com/rain1102/aggbug/290409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/rain1102/" target="_blank">Eric.Zhou</a> 2009-08-09 10:15 <a href="http://www.aygfsteel.com/rain1102/archive/2009/08/09/290409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene全文索小?/title><link>http://www.aygfsteel.com/rain1102/archive/2007/01/29/96436.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Mon, 29 Jan 2007 01:57:00 GMT</pubDate><guid>http://www.aygfsteel.com/rain1102/archive/2007/01/29/96436.html</guid><wfw:comment>http://www.aygfsteel.com/rain1102/comments/96436.html</wfw:comment><comments>http://www.aygfsteel.com/rain1102/archive/2007/01/29/96436.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/rain1102/comments/commentRss/96436.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/rain1102/services/trackbacks/96436.html</trackback:ping><description><![CDATA[<p> <strong> <font color="#006400">HTML 解析?/font> </strong> <br /> <strong> <font color="#000000">package com.rain.util;</font> </strong> </p> <p> <strong> <font color="#000000">import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.FileInputStream;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.FileNotFoundException;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.IOException;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.InputStream;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.InputStreamReader;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.Reader;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.UnsupportedEncodingException;</font> </strong> </p> <p> <strong> <font color="#000000">import org.apache.lucene.demo.html.HTMLParser;</font> </strong> </p> <p> <strong> <font color="#000000">public class HTMLDocParser {</font> </strong> </p> <p> <font color="#000000"> <strong> private String htmlPath;<br /> private HTMLParser htmlParser;<br /> <br /> public HTMLDocParser(String htmlPath){<br />  this.htmlPath=htmlPath;<br />  initHtmlParser();<br /> }<br /> public void initHtmlParser(){<br />  InputStream inputStream=null;<br />  try{<br />   inputStream=new FileInputStream(htmlPath);<br />  }catch(FileNotFoundException e){<br />   e.printStackTrace();<br />  }<br />  if(null!=inputStream){<br />   try{<br />    htmlParser=new HTMLParser(new InputStreamReader(inputStream,"utf-8"));<br />   }catch(UnsupportedEncodingException e){<br />    e.printStackTrace();<br />   }<br />  }<br /> }<br /> public String getTitle(){<br />  if(null!=htmlParser){<br />   try{<br />    return htmlParser.getTitle();<br />   }catch(IOException e){<br />    e.printStackTrace();<br />   }catch(InterruptedException e){<br />    e.printStackTrace();<br />   }<br />  }<br />  return "";<br /> }<br /> public Reader getContent(){<br />  if(null!=htmlParser){<br />   try{<br />    return htmlParser.getReader();<br />   }catch(IOException e){<br />    e.printStackTrace();<br />   }<br />  }<br />  return null;<br /> }<br /> public String getPath(){<br />  return this.htmlPath;<br /> }<br />}<br /></strong> </font> </p> <p> </p> <hr /> <p> </p> <p> <font style="BACKGROUND-COLOR: #ffffff" color="#006400">描述搜烦l果的结构实体Bean<br /><font color="#000000">package com.rain.search;</font></font> </p> <p> <font style="BACKGROUND-COLOR: #ffffff" color="#000000">public class SearchResultBean {<br />    private String htmlPath;<br />    <br />    private String htmlTitle;</font> </p> <p> <font style="BACKGROUND-COLOR: #ffffff" color="#000000"> public String getHtmlPath() {<br />  return htmlPath;<br /> }</font> </p> <p> <font style="BACKGROUND-COLOR: #ffffff" color="#000000"> public void setHtmlPath(String htmlPath) {<br />  this.htmlPath = htmlPath;<br /> }</font> </p> <p> <font style="BACKGROUND-COLOR: #ffffff" color="#000000"> public String getHtmlTitle() {<br />  return htmlTitle;<br /> }</font> </p> <p> <font style="BACKGROUND-COLOR: #ffffff" color="#006400"> <font color="#000000"> public void setHtmlTitle(String htmlTitle) {<br />  this.htmlTitle = htmlTitle;<br /> }<br />}</font> <br /> </font> </p> <p> </p> <hr /> <p> </p> <p> <font color="#000000"> <font color="#006400">索引子系l的实现</font> <br /> <br />package com.rain.index;</font> </p> <p> <font color="#000000">import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.File;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.IOException;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.Reader;</font> </p> <p> <font color="#000000">import org.apache.lucene.analysis.Analyzer;<br />import org.apache.lucene.analysis.standard.StandardAnalyzer;<br />import org.apache.lucene.document.Document;<br />import org.apache.lucene.index.IndexWriter;<br />import org.apache.lucene.store.Directory;<br />import org.apache.lucene.store.FSDirectory;<br />import org.apache.lucene.document.Field;</font> </p> <p> <font color="#000000">import com.rain.util.HTMLDocParser;</font> </p> <p> <font color="#000000">public class IndexManager {<br /> <br /> //the directory that stores HTML files<br /> private final String dataDir="E:\\dataDir";<br /> <br /> //the directory that is used to store a Lucene index<br /> private final String indexDir="E:\\indexDir";<br /> <br /> public boolean creatIndex()throws IOException{<br />  if(true==inIndexExist()){<br />   return true;<br />  }<br />  File dir=new File(dataDir);<br />  if(!dir.exists()){<br />   return false;<br />  }<br />  File[] htmls=dir.listFiles();<br />  Directory fsDirectory=FSDirectory.getDirectory(indexDir,true);<br />  Analyzer analyzer=new StandardAnalyzer();<br />  IndexWriter indexWriter=new IndexWriter(fsDirectory,analyzer,true);<br />  for(int i=0;i<htmls.length;i++){<br />   String htmlPath=htmls[i].getAbsolutePath();<br />   if(htmlPath.endsWith(".html")||htmlPath.endsWith("htm")){<br />    addDocument(htmlPath,indexWriter);<br />   }<br />  }<br />  indexWriter.optimize();<br />  indexWriter.close();<br />  return true;<br /> }<br /> <br /> public void addDocument(String htmlPath,IndexWriter indexWriter){<br />  HTMLDocParser htmlParser=new HTMLDocParser(htmlPath);<br />  String path=htmlParser.getPath();<br />  String title=htmlParser.getTitle();<br />  Reader content=htmlParser.getContent();<br />  <br />  Document document=new Document();<br />  document.add(new Field("path",path,Field.Store.YES,Field.Index.NO));<br />  document.add(new Field("title",title,Field.Store.YES,Field.Index.TOKENIZED));<br />     document.add(new Field("content",content));<br />     try{<br />      indexWriter.addDocument(document);<br />     }catch(IOException e){<br />      e.printStackTrace();<br />     }<br /> }<br /> public String getDataDir(){<br />  return this.dataDir;<br /> }<br /> <br /> public String getIndexDir(){<br />  return this.indexDir;<br /> }<br /> <br /> public boolean inIndexExist(){<br />  File directory=new File(indexDir);<br />  if(0<directory.listFiles().length){<br />   return true;<br />  }else{<br />   return false;<br />  }<br /> }<br />}<br /></font> </p> <p> </p> <hr /> <p> </p> <p>搜烦功能的实?br /><font color="#000000">package com.rain.search;</font></p> <p> <font color="#000000">import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.IOException;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.util.ArrayList;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.util.List;</font> </p> <p> <font color="#000000">import org.apache.lucene.analysis.Analyzer;<br />import org.apache.lucene.analysis.standard.StandardAnalyzer;<br />import org.apache.lucene.queryParser.ParseException;<br />import org.apache.lucene.queryParser.QueryParser;<br />import org.apache.lucene.search.Hits;<br />import org.apache.lucene.search.IndexSearcher;<br />import org.apache.lucene.search.Query;</font> </p> <p> <font color="#000000">import com.rain.index.IndexManager;</font> </p> <p> <font color="#000000">public class SearchManager {<br /> private String searchWord;<br /> private IndexManager indexManager;<br /> private Analyzer analyzer;<br /> <br /> public SearchManager(String searchWord){<br />  this.searchWord=searchWord;<br />  this.indexManager=new IndexManager();<br />  this.analyzer=new StandardAnalyzer();<br /> }<br /> <br /> /**<br />     * do search<br />     */<br /> public List search(){<br />  List searchResult=new ArrayList();<br />  if(false==indexManager.inIndexExist()){<br />   try{<br />    if(false==indexManager.creatIndex()){<br />     return searchResult;<br />    }<br />   }catch(IOException e){<br />    e.printStackTrace();<br />    return searchResult;<br />   }<br />  }<br />  IndexSearcher indexSearcher=null;<br />  try{<br />   indexSearcher=new IndexSearcher(indexManager.getIndexDir());<br />  }catch(IOException e){<br />   e.printStackTrace();<br />  }<br />  QueryParser queryParser=new QueryParser("content",analyzer);<br />  Query query=null;<br />  try{<br />   query=queryParser.parse(searchWord);<br />  }catch(ParseException e){<br />   e.printStackTrace();<br />  }<br />  if(null!=query&&null!=indexSearcher){<br />   try{<br />    Hits hits=indexSearcher.search(query);<br />    for(int i=0;i<hits.length();i++){<br />     SearchResultBean resultBean=new SearchResultBean();<br />     resultBean.setHtmlPath(hits.doc(i).get("path"));<br />     resultBean.setHtmlTitle(hits.doc(i).get("title"));<br />     searchResult.add(resultBean);<br />    }<br />   }catch(IOException e){<br />    e.printStackTrace();<br />   }<br />  }<br />   return searchResult;<br /> }</font> </p> <p> <font color="#000000">}<br /><p></p><hr /></font> </p> <p> <font color="#006400">h理器的实现</font> <br /> <br /> <font color="#000000">package com.rain.servlet;</font> </p> <p> <font color="#000000">import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.io.IOException;<br />import <a title="Java爱好? href="http://www.aygfsteel.com/rain1102" >Java</a>.util.List;</font> </p> <p> <font color="#000000">import javax.servlet.RequestDispatcher;<br />import javax.servlet.ServletException;<br />import javax.servlet.http.HttpServlet;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;</font> </p> <p> <font color="#000000">import com.rain.search.SearchManager;</font> </p> <p> <font color="#000000">/**<br /> * @author zhourui<br /> * 2007-1-28<br /> */<br />public class SearchController extends HttpServlet {<br /> private static final long serialVersionUID=1L;<br /> <br /> /* (non-Javadoc)<br />  * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)<br />  */<br /> @Override<br /> protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {<br />  // TODO Auto-generated method stub<br />  String searchWord=arg0.getParameter("searchWord");<br />  SearchManager searchManager=new SearchManager(searchWord);<br />  List searchResult=null;<br />  searchResult=searchManager.search();<br />  RequestDispatcher dispatcher=arg0.getRequestDispatcher("search.jsp");<br />  arg0.setAttribute("searchResult",searchResult);<br />        dispatcher.forward(arg0, arg1);<br /> }<br /> <br />}</font> <br /> <br /> </p> <hr /> <br /> <strong>向Web服务器提交搜索请?/strong> <br /> <strong><form action="SearchController" method="post"><br />      <table><br />        <tr><br />          <td colspan="3"><br />            SearchWord:<input type="text" name="searchWord" id="searchWord" size="40"><br />            <input id="doSearch" type="submit" value="search"><br />          </td><br />        </tr><br />      </table><br />    </form><br />昄搜烦l果<br /> <table class="result"><br />      <%<br />        List searchResult=(List)request.getAttribute("searchResult");<br />        int resultCount=0;<br />        if(null!=searchResult){<br />         resultCount=searchResult.size();<br />        }<br />        for(int i=0;i<resultCount;i++){<br />         SearchResultBean resultBean=(SearchResultBean)searchResult.get(i);<br />         String title=resultBean.getHtmlTitle();<br />         String path=resultBean.getHtmlPath();<br />         %><br />         <tr><br />           <td class="title"><h3><a href="<%=path%>"><%=title%></a></h3></td><br />         </tr><br />         <%<br />        }<br />      %><br />    </table></strong><img src ="http://www.aygfsteel.com/rain1102/aggbug/96436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/rain1102/" target="_blank">Eric.Zhou</a> 2007-01-29 09:57 <a href="http://www.aygfsteel.com/rain1102/archive/2007/01/29/96436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene基本使用介绍http://www.aygfsteel.com/rain1102/archive/2007/01/28/96356.htmlEric.ZhouEric.ZhouSun, 28 Jan 2007 02:38:00 GMThttp://www.aygfsteel.com/rain1102/archive/2007/01/28/96356.htmlhttp://www.aygfsteel.com/rain1102/comments/96356.htmlhttp://www.aygfsteel.com/rain1102/archive/2007/01/28/96356.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/96356.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/96356.html一.  概述

随着pȝ信息的越来越多,怎么样从q些信息h中捞赯己想要的那一栚w变得非帔R要了Q全文检索是通常用于解决此类问题的方案,而Lucene则ؓ实现全文索的工具QQ何应用都可通过嵌入它来实现全文索?/p>

?  环境搭徏

从lucene.apache.org上下载最新版本的lucene.jarQ将此jar作ؓ目的build pathQ那么在目中就可以直接使用lucene了?/p>

?  使用说明

3.1.       基本概念

q里介绍的主要ؓ在用中l常到一些概念,以大安比较熟悉的数据库来进行类比的讲解Q用Luceneq行全文索的q程有点cM数据库的q个q程Qtable---à查询相应的字D|查询条g----àq回相应的记录,首先是IndexWriterQ通过它徏立相应的索引表,相当于数据库中的tableQ在构徏此烦引表旉指定的ؓ该烦引表采用何种方式q行构徏Q也是说对于其中的记录的字D以什么方式来q行格式的划分,q个在Lucene中称为AnalyzerQLucene提供了几U环境下使用的AnalyzerQSimpleAnalyzer、StandardAnalyzer、GermanAnalyzer{,其中StandardAnalyzer是经怋用的Q因为它提供了对于中文的支持Q在表徏好后我们需要往里面插入用于索引的记录,在Lucene中这个称为DocumentQ有点类似数据库中table的一行记录,记录中的字段的添加方法,在Lucene中称为FieldQ这个和数据库中基本一P对于Field Lucene分ؓ可被索引的,可切分的Q不可被切分的,不可被烦引的几种l合cdQ通过q几个元素基本上可以徏立v索引了。在查询时经常碰到的为另外几个概念,首先是QueryQLucene提供了几U经常可以用到的QueryQTermQuery、MultiTermQuery、BooleanQuery、WildcardQuery、PhraseQuery、PrefixQuery、PhrasePrefixQuery、FuzzyQuery、RangeQuery、SpanQueryQQuery其实也就是指对于需要查询的字段采用什么样的方式进行查询,如模p查询、语义查询、短语查询、范围查询、组合查询等Q还有就是QueryParserQQueryParser可用于创Z同的QueryQ还有一个MultiFieldQueryParser支持对于多个字段q行同一关键字的查询QIndexSearcher概念指的为需要对何目录下的烦引文件进行何U方式的分析的查询,有点象对数据库的哪种索引表进行查询ƈ按一定方式进行记录中字段的分解查询的概念Q通过IndexSearcher以及Query卛_查询出需要的l果QLuceneq回的ؓHits.通过遍历Hits可获取返回的l果的DocumentQ通过Document则可获取Field中的相关信息了?br />

比较一下Lucene和数据库Q?/p>

Lucene 数据?/td>
索引数据源:doc(field1,field2...) doc(field1,field2...)
\ indexer /
_____________
| Lucene Index|
--------------
/ searcher \
l果输出QHits(doc(field1,field2) doc(field1...))
 索引数据源:record(field1,field2...) record(field1..)
\ SQL: insert/
_____________
| DB Index |
-------------
/ SQL: select \
l果输出Qresults(record(field1,field2..) record(field1...))
DocumentQ一个需要进行烦引的“单元”
一个Document由多个字D늻?/td>
RecordQ记录,包含多个字段
FieldQ字D?/td> FieldQ字D?/td>
HitsQ查询结果集Q由匚w的Documentl成 RecordSetQ查询结果集Q由多个Recordl成

通过对于上面在徏立烦引和全文索的基本概念的介l希望能让你对Lucene建立一定的了解?br />

需要熟悉几个接口:
分析器Analyzer
        分析器主要工作是{选,一D|档进来以后,l过它,出去的时候只剩下那些有用的部分,其他则剔除。而这个分析器也可以自己根据需要而编写?br />        org.apache.lucene.analysis.AnalyzerQ这是一个虚构类Q以下两个借口均承它而来?/span>
        org.apache.lucene.analysis.SimpleAnalyzerQ分析器Q支持最单拉丁语a?br />
        org.apache.lucene.analysis.standard.StandardAnalyzerQ标准分析器Q除了拉丁语aq支持亚z语aQƈ在一些匹配功能上q行完善。在q个接口中还有一个很重要的构造函敎ͼStandardAnalyzer(String[] stopWords)Q可以对分析器定义一些用词语,q不仅可以免除检索一些无用信息,而且q可以在索中定义止的政L、非法性的索关键词?/span>
IndexWriter
        IndexWriter的构造函数有三种接口Q针对目录Directory、文件File、文件\径String三种情况?br />例如IndexWriter(String path, Analyzer a, boolean create)Qpath为文件\径,a为分析器Qcreate标志是否重徏索引QtrueQ徏立或者覆盖已存在的烦引,falseQ扩展已存在的烦引。)
       一些重要的ҎQ?/span>

接口??xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>

备注

addDocument(Document doc)

索引d一个文?o:p>

addIndexes(Directory[] dirs)

目录中已存在烦引添加到q个索引

addIndexes(IndexReader[] readers)

提供的索引d到这个烦?o:p>

optimize()

合ƈ索引q优?o:p>

close()

关闭

 
       IndexWriterZ减少大量的iol护操作Q在每得C定量的烦引后建立新的烦引文ӞW者测试烦引批量的最单位ؓ10Q,然后再定期将它们整合C个烦引文件中Q因此在索引l束时必进行wirter.optimize()Q以便将所有烦引合q优化?br />
org.apache.lucene.document
 以下介绍两种主要的类Q?br /> aQorg.apache.lucene.document.DocumentQ?br />        Document文档cM数据库中的一条记录,可以由好几个字段QFieldQ组成,q且字段可以套用不同的类型(详细见bQ。Document的几U接口: 

接口?o:p>

备注

add(Field field)

d一个字D(FieldQ到Document?o:p>

String get(String name)

从文档中获得一个字D对应的文本

Field getField(String name)

由字D名获得字段?o:p>

Field[] getFields(String name)

由字D名获得字段值的?o:p>


 bQorg.apache.lucene.document.Field
        即上文所说的“字段”Q它是Document的片Dsection?br />        Field的构造函敎ͼ
       Field(String name, String string, boolean store, boolean index, boolean token)?br />        IndexedQ如果字D|Indexed的,表示q个字段是可索的?br />        StoredQ如果字D|Stored的,表示q个字段的值可以从索结果中得到?br />        TokenizedQ如果一个字D|Tokenized的,表示它是有经qAnalyzer转变后成Z个tokens序列Q在q个转变q程tokenization中,Analyzer提取出需要进行烦引的文本Q而剔除一些冗余的词句Q例如:aQthe,they{,详见org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS和org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords)的APIQ。Token是烦引时候的基本单元Q代表一个被索引的词Q例如一个英文单词,或者一个汉字。因此,所有包含中文的文本都必LTokenized的?br />     Field的几U接口:

Name

Stored

Indexed

Tokenized

use

Keyword(String name,

        String value)

Y

Y

N

date,url

Text(String name, Reader value)

N

Y

Y

short text fields:

title,subject

Text(String name, String value)

Y

Y

Y

longer text fields,

like “body”

UnIndexed(String name,

String value)

Y

N

N

 

UnStored(String name,

         String value)

N

Y

Y

 

Hits与Searcher
       Hits的主要用接口:

接口?o:p>

备注

Doc(int n)

q回Wn个的文档的所有字D?o:p>

length()

q回q个集中的可用个?o:p>


3.2.       全文索需求的实现

索引建立部分的代码:


private void createIndex(String indexFilePath) throws Exception{

        IndexWriter iwriter=getWriter(indexFilePath);

        Document doc=new Document();

        doc.add(Field.Keyword("name","jerry"));

        doc.add(Field.Text("sender","bluedavy@gmail.com"));

        doc.add(Field.Text("receiver","google@gmail.com"));

        doc.add(Field.Text("title","用于索引的标?));

        doc.add(Field.UnIndexed("content","不徏立烦引的内容"));

        Document doc2=new Document();

        doc2.add(Field.Keyword("name","jerry.lin"));

        doc2.add(Field.Text("sender","bluedavy@hotmail.com"));

        doc2.add(Field.Text("receiver","msn@hotmail.com"));

        doc2.add(Field.Text("title","用于索引的第二个标题"));

        doc2.add(Field.Text("content","建立索引的内?));

        iwriter.addDocument(doc);

        iwriter.addDocument(doc2);

        iwriter.optimize();

        iwriter.close();

    }

   

    private IndexWriter getWriter(String indexFilePath) throws Exception{

        boolean append=true;

        File file=new File(indexFilePath+File.separator+"segments");

        if(file.exists())

            append=false;

        return new IndexWriter(indexFilePath,analyzer,append);

    }


3.2.1.       对于某字D늚关键字的模糊查询


Query query=new WildcardQuery(new Term("sender","*davy*"));

       

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(query);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


3.2.2.       对于某字D늚关键字的语义查询


Query query=QueryParser.parse("索引","title",analyzer);

       

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(query);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


3.2.3.       对于多字D늚关键字的查询


Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);

       

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(query);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


3.2.4.       复合查询(多种查询条g的综合查?


Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);

        Query mquery=new WildcardQuery(new Term("sender","bluedavy*"));

        TermQuery tquery=new TermQuery(new Term("name","jerry"));

       

        BooleanQuery bquery=new BooleanQuery();

        bquery.add(query,true,false);

        bquery.add(mquery,true,false);

        bquery.add(tquery,true,false);

       

        Searcher searcher=new IndexSearcher(indexFilePath);

        Hits hits=searcher.search(bquery);

        for (int i = 0; i < hits.length(); i++) {

            System.out.println(hits.doc(i).get("name"));

        }


?  ȝ

怿大家通过上面的说明能知道Lucene的一个基本的使用ҎQ在全文索时大家先采用语义时的搜索,先搜索出有意义的内容Q之后再q行模糊之类的搜索,^_^Q这个还是需要根据搜索的需求才能定了,Luceneq提供了很多其他更好用的ҎQ这个就{待大家在用的q程中自己去q一步的摸烦了,比如对于Lucene本n提供的Query的更熟练的掌握,对于Filter、Sorter的用,自己扩展实现AnalyzerQ自己实现Query{等Q甚臛_以去了解一些关于搜索引擎的技?切词、烦引排?etc){等



Eric.Zhou 2007-01-28 10:38 发表评论
]]>
վ֩ģ壺 | Ǭ| | | | ǭ| »| ʡ| ³ľ| Ϫ| | | | ʡ| Դ| | ׶| | | | ̩| | | | ̩| ͭɽ| ɰ| | ɽ| | ϲ| | ƽ| ƽ| Ǩ| | | | ɽ| | |