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

          北京好奇怪,晝夜溫差很大,有點(diǎn)像月球。早起時(shí)窗上的冰霜很厚實(shí),但到了白天陽(yáng)光很足,風(fēng)力很小,氣溫很好。大連現(xiàn)在確在降溫,零下十幾度,比較罕見(jiàn)??赡苁俏译x開(kāi)她一會(huì),她卻變冷了。呵呵~~

           

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

           

          一、lucene高級(jí)

          1.分詞器

          一般的分詞器流程:

          clip_image001
           

           


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

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

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

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

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

           

          Lucene中的分詞器

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

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

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

          示例:

          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();// 詞庫(kù)分詞

           

              @Test

              public void test() throws IOException {

                  String str = "中國(guó)人加油!";

                  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();// 詞庫(kù)分詞器

           

              @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", "中國(guó)人民加油!", 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í)算出來(lái)的。

          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)”提升對(duì)應(yīng)字段內(nèi)容的排名。一般網(wǎng)站內(nèi)部搜索會(huì)將標(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.過(guò)濾器

          在查詢時(shí)添加一個(gè)過(guò)濾器,過(guò)濾掉查詢后不想要的內(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的子類對(duì)應(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,短語(yǔ)查詢:

          PhraseQuery phraseQuery = new PhraseQuery();

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

          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", "中國(guó)人民"));

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

          二、Compass

          Compasslucene的框架,它與hibernate極其相似(但不具有hibernate那些高級(jí)功能,比如緩存技術(shù))。湯兄弟做的好,因?yàn)閷W(xué)習(xí)lucene之前的課程正是hibernate,他將hibernatecompass對(duì)比了一下,使我們學(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”手冊(cè),內(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);

           

           

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


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 冷水江市| 巴塘县| 怀化市| 涟水县| 平舆县| 平度市| 车致| 古丈县| 斗六市| 丰城市| 府谷县| 九龙县| 盱眙县| 尼勒克县| 汝城县| 高台县| 苏尼特右旗| 榆林市| 商洛市| 呼图壁县| 吴桥县| 同江市| 汪清县| 抚顺县| 松原市| 蒙阴县| 金山区| 哈巴河县| 察雅县| 许昌市| 湛江市| 保定市| 日喀则市| 佛山市| 民和| 天气| 拜泉县| 连南| 玉山县| 玉溪市| 门头沟区|