posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          2010-01-05 傳智播客—luncene/compass

          Posted on 2010-01-06 16:51 長城 閱讀(1494) 評論(0)  編輯  收藏

          北京好奇怪,晝夜溫差很大,有點(diǎn)像月球。早起時(shí)窗上的冰霜很厚實(shí),但到了白天陽光很足,風(fēng)力很小,氣溫很好。大連現(xiàn)在確在降溫,零下十幾度,比較罕見。可能是我離開她一會,她卻變冷了。呵呵~~

           

          今日上午把lucene的高級部分給結(jié)束了。下午搞了一下CompassCompass是對lucene的封閉。因?yàn)?/span>lucene使用起來有些麻煩。

           

          一、lucene高級

          1.分詞器

          一般的分詞器流程:

          clip_image001
           

           


          1)         輸入文本:輸入查詢的內(nèi)容。

          2)         關(guān)鍵詞切分:使用分詞器取出關(guān)鍵詞。

          3)         去除停用詞:去除沒有多大意義的詞,比如a,an,the,的,呢,吧。

          4)         形態(tài)還原:將詞的某種形態(tài)還原為原形,比如英文復(fù)數(shù)形式恢復(fù)到單數(shù)形式。

          5)         轉(zhuǎn)為小寫:將英文轉(zhuǎn)為小寫,不區(qū)分大小寫。

           

          Lucene中的分詞器

          1)         單字分詞:對應(yīng)的類ChineseAnalyzer,將輸入的字符串中的每個(gè)字做為關(guān)鍵字。比如“中國人加油!”,會被切分為“中”、“國”、“人”、“加”、“油”。(標(biāo)點(diǎn)符號屬于停用詞)

          2)         二分法分詞:對應(yīng)的類CJKAnalyzer,將輸入的字符串以二分法分詞。比如“中國人加油!”,會被切分為“中國”、“國人”、“人加”、“加油”這四個(gè)關(guān)鍵字。(標(biāo)點(diǎn)符號屬于停用詞)

          3)         詞庫分詞:對應(yīng)的類MMAnalyzer最為常用的分詞器。比如“中國人加油!”,會被切分為“中國人”、“加油”。(標(biāo)點(diǎn)符號屬于停用詞)

          示例:

          package cn.itcast.cc.anayzler;

           

          import java.io.IOException;

          import java.io.StringReader;

          import jeasy.analysis.MMAnalyzer;

          import org.apache.lucene.analysis.Analyzer;

          import org.apache.lucene.analysis.Token;

          import org.apache.lucene.analysis.TokenStream;

          import org.apache.lucene.analysis.cjk.CJKAnalyzer;

          import org.apache.lucene.analysis.cn.ChineseAnalyzer;

          import org.junit.Test;

           

          public class AnalyzerTest {

           

              Analyzer anaylzer1 = new ChineseAnalyzer();// 單字分詞

              Analyzer anaylzer2 = new CJKAnalyzer();// 二分分詞法

              Analyzer anaylzer3 = new MMAnalyzer();// 詞庫分詞

           

              @Test

              public void test() throws IOException {

                  String str = "中國人加油!";

                  printAnalyzer(anaylzer1, str);

                  printAnalyzer(anaylzer2, str);

                  printAnalyzer(anaylzer3, str);

              }

           

              private void printAnalyzer(Analyzer analyzer, String str)

                      throws IOException {

                  TokenStream tokenStream = analyzer.tokenStream("text", new StringReader(

                          str));

                  System.out.println("*****分詞器->" + analyzer.getClass().getName() + ",將'"

                          + str + "'切分為:");

                  Token token = new Token();

                  while ((token = tokenStream.next(token)) != null) {

                      System.out.println(token);

                  }

              }

          }

           

          2.高亮

          Lucene的高亮器(Highlighter類)可以實(shí)現(xiàn)lucene的關(guān)鍵字高亮:

          package cn.itcast.cc.highlighter;

           

          import org.apache.lucene.analysis.Analyzer;

          import org.apache.lucene.document.*;

          import org.apache.lucene.document.Field.*;

          import org.apache.lucene.index.IndexWriter;

          import org.apache.lucene.index.IndexWriter.MaxFieldLength;

          import org.apache.lucene.queryParser.*;

          import org.apache.lucene.search.*;

          import org.apache.lucene.search.highlight.*;

          import org.apache.lucene.search.highlight.Scorer;

          import org.junit.Test;

          import jeasy.analysis.MMAnalyzer;

           

          public class HighLighterTesst {

              private String path = "./index/";// lucene的索引數(shù)據(jù)被保存在這個(gè)目錄中

              private Analyzer analyzer = new MMAnalyzer();// 詞庫分詞器

           

              @Test

              public void test() {

                  try {

                      // 創(chuàng)建索引數(shù)據(jù)

                      IndexWriter indexWriter = new IndexWriter(this.path, this.analyzer,

                              MaxFieldLength.LIMITED);

                      Document doc = new Document();

                      doc.add(new Field("content", "中國人民加油!", Store.YES, Index.ANALYZED));

                      indexWriter.addDocument(doc);

                      indexWriter.close();

                      // 查詢數(shù)據(jù)

                      IndexSearcher indexSearcher = new IndexSearcher(this.path);

                      QueryParser queryParser = new MultiFieldQueryParser(

                              new String[] { "content" }, this.analyzer);

                      Query query = queryParser.parse("加油");

                      TopDocs topDocs = indexSearcher.search(query, null, 10);

                      // 創(chuàng)建高亮

                      // SimpleHTMLFormatter的默認(rèn)值為"<a></a>"

                      Formatter formatter = new SimpleHTMLFormatter("<span>", "</span>");

                      Scorer scorer = new QueryScorer(query);

                      Highlighter highlighter = new Highlighter(formatter, scorer);

                      // 打印結(jié)果

                      for (ScoreDoc scoreDoc : topDocs.scoreDocs) {

                          // 取出查詢結(jié)果

                          Document searchdoc = indexSearcher.doc(scoreDoc.doc);

                          String searchstr = searchdoc.getField("content").stringValue();

                          // 添加高亮

                          String histr = highlighter.getBestFragment(this.analyzer,

                                  "content", searchstr);

                          System.out.println(histr);

                      }

                      indexSearcher.close();

                  } catch (Exception e) {

                      e.printStackTrace();

                  }

              }

          }

           

          3.排序(默認(rèn)相關(guān)度排序)

          a)          實(shí)驗(yàn)相關(guān)度排序,得分是在搜索時(shí)算出來的。

          b)         影響區(qū)域

          i.           整個(gè)文檔

          ii.          某個(gè)字段

          1.          建立索引時(shí),影響它的排名,創(chuàng)建QueryParser時(shí)指定“MultiFieldQueryParser(String[] fields, Analyzer analyzer, Map boosts)”中第三個(gè)參數(shù)為“new HashMap<String, Float>().put(String fieldname, float fraction)”提升對應(yīng)字段內(nèi)容的排名。一般網(wǎng)站內(nèi)部搜索會將標(biāo)題部分的內(nèi)容提升,以至于標(biāo)題內(nèi)容的排名大于帖子內(nèi)容或回復(fù)的排名。

          2.          搜索時(shí),標(biāo)題與內(nèi)容的含量排名,TopDoc有一個(gè)score屬性,它是根據(jù)文檔中關(guān)鍵字的數(shù)量,記錄文檔的得分。

          c)   按指定的字段進(jìn)行排序,就是在搜索時(shí),指定的字段。

          d)   Sort排序器,由類Sort實(shí)現(xiàn)。

          Sort sort = new Sort();

          sort.setSort(SortField field);

          indexSearcher.search(query, null, 100, sort);

           

          4.過濾器

          在查詢時(shí)添加一個(gè)過濾器,過濾掉查詢后不想要的內(nèi)容,由Filter接口實(shí)現(xiàn)。

          String lower = NumberTools.longToString(3);

          String upper = NumberTools.longToString(6);

          Filter filter = new RangeFilter("id", lower, upper, true, false);

          indexSearcher.search(query, filter, 100);

          lucene中使用數(shù)值、日期數(shù)據(jù)時(shí),必須使用NumberToolsDateTools。前后必須統(tǒng)一,比如使用longToStringLong轉(zhuǎn)換為String,那么也必須使用stringToLongString轉(zhuǎn)換為Long

           

          5.搜索,Query的子類對應(yīng)各種查詢:

          1)         TermQuery,關(guān)鍵詞查詢:

          Term term = new Term("context", "加油");

          Query query = new TermQuery(term);

          indexSearcher.search(query, null, 100);

          2)         RangeQuery,范圍查詢:

          Term lower = new Term("content", NumberTools.longToString(3));

          Term upper = new Term("content", NumberTools.longToString(10));

          Query query = new RangeQuery(lower, upper, false/*包含邊界*/);

          indexSearcher.search(query, null, 100);

          3)         WildcardQuery,通配符查詢:

          Term term = new Term("context", "?");//?匹配任意一個(gè)字符,*代表任意多個(gè)字符。

          Query query = new TermQuery(term);

          indexSearcher.search(query, null, 100);

          indexSearcher.search(query, null, 100);

          4)         PhraseQuery,短語查詢:

          PhraseQuery phraseQuery = new PhraseQuery();

          phraseQuery.add(new Term("context", "中國人民"));

          phraseQuery.add(new Term("context", "加油"));

          phraseQuery.setSlop(5); // 指定關(guān)鍵詞之間間隔的字符的最大數(shù)量

          indexSearcher.search(query, null, 100);

          5)         BooleanQuery,布爾查詢:

          Query query1 = new TermQuery(new Term("context", "中國人民"));

          Query query2 = new TermQuery(new Term("context", "加油"));

          BooleanQuery boolQuery = new BooleanQuery();

          boolQuery.add(query1, Occur.MUST);

          boolQuery.add(query2, Occur.SHOULD);//Occur的常量值:MUSTSHOULDMUST_NOT

          indexSearcher.search(query, null, 100);

          注意:經(jīng)過分詞器的所有字母,無論是添加索引還是查詢,都會被轉(zhuǎn)換為小寫的。但上邊這些查詢類沒有經(jīng)過分詞器,如果查詢關(guān)鍵里有大寫字母,將查詢不到匹配的結(jié)果。所以在使用上邊這些查詢類時(shí),查詢文本中的字母全部為小寫。我們之前使用的查詢是通過QueryParser切分出查詢關(guān)鍵字,所以使用QueryParser可以不注意大小寫問題。

          二、Compass

          Compasslucene的框架,它與hibernate極其相似(但不具有hibernate那些高級功能,比如緩存技術(shù))。湯兄弟做的好,因?yàn)閷W(xué)習(xí)lucene之前的課程正是hibernate,他將hibernatecompass對比了一下,使我們學(xué)習(xí)compass更加容易了。OK,我總結(jié)一下。

          1.hibernatecompass

          clip_image001[3]

           

          clip_image001[5]

           


          hibernate

          compass

          配置方式

          1.編程方式:

            Configuation cfg = new Configu...();

            cfg.set...();

            ...

          2.配置文件:

            //默認(rèn)配置,文件名為“hibernate.cfg.xml

            Configuation cfg= new Configu...();

          //指定文件名(文件名可變更)

          //cfg.configure("hibernate.cfg.xml");

          1.編程方式:

            CompassConfiguation cfg = new CompassConf...();

            cfg.set("key","value");

            ...

          2.配置文件

            //默認(rèn)配置,文件名為“compass.cfg.xml

            cfg.configure();

            //指定文件名(文件名可變更)

            cfg.configure("hibernate.cfg.xml");

          配置文件

          XML文件

          注解

          XML文件

          注解

           

          2.compass中的注解配置

          package cn.itcast.cc.compass;

           

          import org.compass.annotations.Index;

          import org.compass.annotations.Searchable;

          import org.compass.annotations.SearchableId;

          import org.compass.annotations.SearchableProperty;

          import org.compass.annotations.Store;

           

          @Searchable

          public class Article {

              private Long id;

              private String title;

              private String content;

              @SearchableId

              public Long getId() { return id;}

              @SearchableProperty(store = Store.YES, index = Index.ANALYZED, boost = 2.0F, excludeFromAll = ExcludeFromAll.YES/*這個(gè)屬性的內(nèi)容被查詢忽略*/)

              public String getTitle() {return title;}

              @SearchableProperty(store = Store.YES, index = Index.ANALYZED)

              public String getContent() {return content;}

              public void setId(Long id) {this.id = id;}

              public void setTitle(String title) {this.title = title;}

              public void setContent(String content) {this.content = content;}

          }

          XML配置文件,可以查看“compass-2.2.0-M2/docs/reference/html_single/index.html”手冊,內(nèi)容較多。

          3.compassAPI

          CompassConfiguration cfg = new CompassConfiguration();

          cfg.setConnection("./indexPath/");// 連接信息

          cfg.addClass(Article.class);// 聲明映射信息

          Compass compassSessionFactory = cfg.buildCompass();

          CompassTransaction tx = session.beginTransaction();

          session.create(article);

          tx.commit();

          session.close();

          其他API

          session.find(String arg0);

          session.save(Object arg0);

          session.delete(Class arg0, Object arg1);

           

           

          這兩天的課程相對比較容易些,雖然容易但仍然需要一定的練習(xí)。后天就要學(xué)習(xí)jbpmOA項(xiàng)目了,終于開始第一個(gè)像樣的項(xiàng)目了,呵呵!不過感覺并沒想像中的那么復(fù)雜,因?yàn)橛辛?/span>jbpm


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 集贤县| 湘潭县| 西和县| 奉贤区| 子长县| 宿松县| 盐边县| 清徐县| 彩票| 宾阳县| 大兴区| 崇州市| 华宁县| 恭城| 图木舒克市| 乡宁县| 阳高县| 博客| 丰原市| 工布江达县| 斗六市| 无棣县| 景德镇市| 浮山县| 萨迦县| 长乐市| 新建县| 太保市| 景德镇市| 定日县| 北票市| 绵阳市| 手机| 四子王旗| 沙田区| 宜兰市| 旬阳县| 台北县| 新源县| 房产| 忻州市|