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

          2010-01-04 傳智播客—luncene

          Posted on 2010-01-04 21:26 長城 閱讀(704) 評論(0)  編輯  收藏

                   我們這些網民,見得多了檢索應用了。Google、百度、論壇內部搜索、網站內部搜索,這些應用使用的就是檢索技術。今天我們學習的主要是針對WEB應用的內部文本檢索,比如論壇。我們使用的框架是lucene。授課老師是湯陽光,年輕有為!

           

                   搞技術的,看到什么新技術總是十分好奇。先不說googlebaidu吧(他們的專業檢索技術很強哦),見到論壇內部的檢索功能,就讓我十分好奇。我原本以為論壇內部的檢索就是模糊查找數據庫,但今日的課程讓我學習到了論壇內部真正的檢索技術。

           

          一、信息檢索和全文檢索

          信息檢索就是從信息集合中找出與用戶需求相關的信息。被檢索的信息除了文本外,還有圖像、音頻、視頻等多媒體信息。我們只關注文本的檢索,把用戶的查詢請求和全文中的每一個詞進行比較,不考慮查詢請求與文本語義上的匹配,這叫做全文檢索。在信息檢索工具中,全文檢索是最具通用性和實用性的。例如,使用百度從一大堆網頁中搜出與“傳智播客”相關的網頁。

           

          我們簡單看一下檢索技術的流程:

          請求

          clip_image001

           

          上面可見索引數據庫是十分重要的,簡單的說。全文檢索系統,將網絡上的數據通過某種格式保存到索引庫中。當用戶發送查詢請求時,實質上就是向索引庫查詢。全文檢索引擎負責處理用戶的請求用索引庫的更新等。

           

          小時候查的漢語字典、英語詞典我們是如何查詢的?當然不是一頁一頁的翻了,靠的是字典的目錄。Lucene的檢索方式正是使用了此技術,lucene的索引庫格式:

          檢索目錄

           

          數據

          索引

          關鍵字

          索引

          Documents…

          1

          C、匯編

          1

          匯編比機器在語言高級…C比匯編高級

          2

          C++

          2

          C++C高級..

          3

          JavaJ2E

          3

          JAVA應用級,最為優秀的語言

          4

          WEB

          4

          WEB是真正的計算機

          5

          你好

          5

          Hi,你好啊!

           

           

                   上面的表只是簡單說明lucene索引庫的存儲格式。我們通過lucene提供的類可以向索引庫添加、修改、查詢、刪除操作

           

                   關鍵字是通過分詞器分析出來的,一般情況下各有語言有各字的分詞器。分詞器的強大提高了查詢數據的接近性。

           

          二、lucene操作

                   我們編寫一個對Article對象向lucene索引庫的添加、修改、查詢、刪除操作:

          import java.util.ArrayList;

          import java.util.List;

          import org.apache.lucene.analysis.Analyzer;

          import org.apache.lucene.analysis.standard.StandardAnalyzer;

          import org.apache.lucene.index.IndexWriter;

          import org.apache.lucene.index.Term;

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

          import org.apache.lucene.queryParser.MultiFieldQueryParser;

          import org.apache.lucene.queryParser.QueryParser;

          import org.apache.lucene.search.IndexSearcher;

          import org.apache.lucene.search.Query;

          import org.apache.lucene.search.TopDocs;

          import cn.itcast.cc.lucene.helloword.Article;

          import cn.itcast.cc.lucene.helloword.utils.ArticleDocUtils;

           

          public class IndexDao {

              // 索引目錄

              private String indexPath = "./index";

              // 分詞器

              private Analyzer analyzer = new StandardAnalyzer();

           

              /**

               * 保存記錄

               *

               * @param art

               */

              public void save(Article art) {

                  // lucene的寫出索引類

                  IndexWriter indexWriter = null;

                  try {

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

                              MaxFieldLength.LIMITED);

                      // 添加到索引庫

                      indexWriter.addDocument(ArticleDocUtils.Article2Doc(art));

                  } catch (Exception e) {

                      e.printStackTrace();

                  }

                  // 釋放indexWriter

                  if (indexWriter != null) {

                      try {

                          // 使用后一定要關閉

                          indexWriter.close();

                      } catch (Exception e) {

                          e.printStackTrace();

                      }

                  }

              }

           

              /**

               * 更新記錄

               *

               * @param art

               */

              public void update(Article art) {

                  IndexWriter indexWriter = null;

                  try {

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

                              MaxFieldLength.LIMITED);

                      Term term = new Term("id", art.getId() + "");

                      // 更新

                      indexWriter.updateDocument(term, ArticleDocUtils.Article2Doc(art));

                  } catch (Exception e) {

                      e.printStackTrace();

                  }

           

                  // 釋放indexWriter

                  if (indexWriter != null) {

                      try {

                          indexWriter.close();

                      } catch (Exception e) {

                          e.printStackTrace();

                      }

                  }

              }

           

              /**

               * 刪除記錄

               *

               * @param id

               */

              public void delete(int id) {

                  IndexWriter indexWriter = null;

                  try {

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

                              MaxFieldLength.LIMITED);

                      Term term = new Term("id", id + "");

                      // 刪除

                      indexWriter.deleteDocuments(term);

                  } catch (Exception e1) {

                      e1.printStackTrace();

                  }

           

                  // 釋放indexWriter

                  if (indexWriter != null) {

                      try {

                          indexWriter.close();

                      } catch (Exception e) {

                          e.printStackTrace();

                      }

                  }

              }

           

              /**

               * 查詢記錄(具有分頁功能)

               *

               * @param queryString

               * @param startIndex

               * @param recordCount

               * @return

               */

              public List search(String queryString, int startIndex, int recordCount) {

                  List result = new ArrayList();

                  IndexSearcher indexSearcher = null;

                  try {

                      indexSearcher = new IndexSearcher(this.indexPath);

                      String[] fields = new String[] {"title","content"};

                      // 分析查詢條件

                      QueryParser queryParser = new MultiFieldQueryParser(fields,

                              this.analyzer);

                      // 生成查詢對象

                      Query query = queryParser.parse(queryString);

                      int findTotalRecord = startIndex + recordCount;

                      // 查詢

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

                      //獲取分頁數據

                      int endIndex = Math.min(startIndex+recordCount,topDocs.totalHits);

                      for(int i=startIndex; i<endIndex;i++){

                          result.add(indexSearcher.doc(topDocs.scoreDocs[i].doc));

                      }

           

                  } catch (Exception e1) {

                      e1.printStackTrace();

                  }

           

                  // 釋放indexWriter

                  if (indexSearcher != null) {

                      try {

                          indexSearcher.close();

                      } catch (Exception e) {

                          e.printStackTrace();

                      }

                  }

                  return result;

              }

          }

           

                   其中使用到的“ArticleDocUtils”如下:

          import org.apache.lucene.document.Document;

          import org.apache.lucene.document.Field;

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

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

          import cn.itcast.cc.lucene.helloword.Article;

           

          public class ArticleDocUtils {

              public static Document Article2Doc(Article art){

                  // lucene索引庫中的document對象

                  Document doc = new Document();

                  // 添加到document中的都是field對象,注冊其中的key,檢索時會用到。

                  // Store是否存儲,決定對象是臨時性還是持久性的

                  // Index在庫中建立什么樣的索引

                  doc.add(new Field("id", art.getId()+"", Store.YES, Index.NOT_ANALYZED));

                  doc.add(new Field("title", art.getTitle(), Store.YES, Index.ANALYZED));

                  doc.add(new Field("content", art.getContent(), Store.YES, Index.ANALYZED));

                  return doc;

              }

             

              public static Article Doc2Article(Document doc){

                  Article art = new Article();

                 

                  art.setId(Integer.parseInt(doc.getField("id").stringValue()));

                  art.setTitle(doc.getField("title").stringValue());

                  art.setContent(doc.getField("content").stringValue());

                  return art;

              }

           

                   需要導入的jar包:lucene-analyzers-2.4.0.jarlucene-core-2.4.0.jarlucene-highlighter-2.4.0.jar

           

                   上面是對lunce的簡單操作,明天會講解檢索的分詞器、高亮、排序、過濾

           

                   湯老師今天有留練習作業,我去做練習了哦~~ lucene很簡單、很方便~~


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


          網站導航:
           
          主站蜘蛛池模板: 江山市| 军事| 准格尔旗| 金秀| 呼图壁县| 曲周县| 突泉县| 古浪县| 马公市| 无棣县| 来安县| 南平市| 青神县| 元氏县| 鹰潭市| 大竹县| 凤庆县| 武清区| 灵川县| 丹巴县| 湘潭市| 鹿邑县| 平潭县| 郎溪县| 无锡市| 九龙城区| 龙里县| 佳木斯市| 同德县| 达州市| 罗城| 溧水县| 焦作市| 滨海县| 宾阳县| 汽车| 广饶县| 固原市| 元朗区| 曲阳县| 湟中县|