lucene

搜索功能:lucene
全文檢索:以文本作爲檢索對象,找出含有指定詞彙的文本,全面準確和快速是衡量全文檢索的關鍵指標,特點:只處理文本,不處理語義,搜索時英文不區分大小寫,結果列表有相關度排序
全文檢索不同於數據庫的檢索:
全文檢索不同於數據庫的SQL查詢。(他們所解決的問題不一樣,解決的方案也不一樣,所以不應進行對比)。在數據庫中的搜索就   是使用SQL,
    如:SELECT * FROM table WHERE content like ‘%ant%’。這樣會有如下問題:
    1、匹配效果:如搜索ant會搜索出planting,plant,ant。這樣就會搜出很多無關的信息。
    2、相關度排序:查出的結果沒有相關度排序,不知道我想要的結果在哪一頁。我們在使用百度搜索時,一般不需要翻頁,爲什麼?因爲百度做了相關度排序:爲每一條結果打一個分數,這條結果越符合搜索條件,得分就越高,叫做相關度得分,結果列表會按照這個分數由高到低排列,所以第1頁的結果就是我們最想要的結果。
    3、全文檢索的速度大大快於SQL的like搜索的速度。這是因爲查詢方式不同造成的,以查字典舉例:數據庫的like就是一頁一頁的翻,一行一行的找,而全文檢索是先查目錄,得到結果所在的頁碼,再直接翻到這一頁
lucene相當於索引庫,
hello world:
indexwriter:創建索引庫
指定索引庫的目錄位置:fsdirectory.open(new file(""));
指定分詞器,創建索引庫時按某種分詞來創建索引庫:new standaranalyzer(version.lucene_30)
限定分詞:一個句子最多能分多少個詞,最大分詞默認值爲10000
將article轉化爲document:
doc.add(new Field("id",article.getId().toString(),Store.YES,Index.ANALYZED));
  * Stroe:表示是否將該字段的值存儲到數據區域
      (1):YES:將該字段的值存儲到索引庫的數據區域,如果將該值存儲到數據區域,那麼在檢索的時候,就能夠檢索到該字段的值
      (2):NO:將該字段的值不存儲到索引庫的數據區域,如果將該值沒有存儲到數據區域,那麼在檢索的時候,就不能夠檢索到該字段的值,返回是null
  * Index:表示將數據一定要存儲索引庫的數據區域,是否對索引庫的目錄區域進行操作
      (1):ANOLAZER:將數據一定要存儲到索引庫的數據區域,此時將該值要存儲到目錄區域一份,同時對該值進行分詞,將分詞後的值放置到索引庫的目錄區域
      (2):NOT_ANOLAZER:將數據一定要存儲到索引庫的數據區域,此時將該值要存儲到目錄區域一份,同時對該值不進行分詞,將整個詞的值放置到索引庫的目錄區域
          例如:id,日期,姓名
      (3):NO:將數據一定要存儲到索引庫的數據區域,此時不將該值放置到目錄區域,如果不放置到目錄區域,此時不能通過索引庫進行檢索

field:向文檔中添加字段及字段的值,參數1:爲索引庫中的字段命名,參數2:將值放置到數據庫定義的字段中,參數3:yes:將該字段的值存儲到索引庫的數據區域,如果將該值存儲到數據區域,那麼在檢索的時候,就能夠檢索到該字段的值  參數4:analyzed:表示一定要存儲索引庫的數據區域,此時將該值要存儲到目錄區域一份,同時,對該值進行分詞,將分此後的值放置到索引庫的目錄區域not_anolazed:表示一定要存儲索引庫的數據區域,此時將該值要存儲到目錄區域一份,同時,對該值進行分詞,將整個詞的值放置到索引庫的目錄區域
no:表示一定要存儲索引庫的數據區域,此時不將該值放置到目錄區域,如果不放知道目錄區域,此時不能通過索引庫進行檢索
例如:id,日期,姓名不能進行分詞
索引庫中對應兩個區域:目錄區域,和數據區域:在索引庫中產生一個內部編號,在檢索時通過內部編號進行檢索,默認是0)

關閉:indexwriter.close();
indexwriter.adddocument(文檔),文檔中有字段:ID,title,content
檢索索引庫:
IndexSearcher indexSearcher = new IndexSearcher();
   indexSearcher.search(query,n);

indexsearcher.search(query:封裝檢索的條件,n:返回的結果記錄數)
queryparse:封裝檢索條件,針對每個字段進行查詢
queryparse。parse(查詢條件)
針對多個字段進行查詢:queryparser=new multifieldqueryparser(版本號,new string[]{},分詞器)
通過索引庫中存在的內部編號獲取document對象,將document對象轉換爲article了對象,顯示article的對象
要保證數據庫和索引庫時一致的,具體索引庫的操作,是調用相應的indexDao方法完成,此類類似於數據庫層的DAO
lucene的CRUD:
1:創建索引庫
2:刪除索引庫
team用於爲索引庫中某個字段指定值team  team=new  term(“”,id.tostring)
2:更新索引庫updateDocument(term,document)
索引文件的檢索與維護,更新是先刪除後創建
測試類:

3:搜索索引庫
若不關閉indexwriter,將產生異常,一個線程中,只能存在一個indexwriter對象,並用該對象操作索引庫,如果還需要使用第二個indexwriter對象,需要將第一個indexwriter對象關閉,否則會出現異常
同時使用indexwriter和indexsearcher
索引庫的優化:將多個索引庫的文件合併爲一個文件
Optimize:將一個索引庫中的多個文件合併爲一個文件,如果使用optimize進行優化,需要有足夠大的硬盤空間
合併索引庫文件:setmergefactor:指定參數用來合併索引庫的文件,參數表示當索引庫中的數據文件到了幾個文件後就自動合併,eg:參數爲3:索引庫中的數據文件到了3個文件後就自動合併,此參數最小值是2,最大值是10;使用該方法時,不能自動執行,必須要向索引庫中添加數據的時候,才能執行優化合並
內存索引庫:RAMDrictory,是虛擬的文件夾和文件
當操作完之後,將虛擬內存中的索引庫的數據放置到真實索引庫中
分詞器:創建和檢索使用同一個分詞器(分詞器工作步驟:切分關鍵詞,去除停用詞,將大寫英文字母轉化爲小寫字母)
單字分詞:eg:標準分詞器,中文分詞器ChineseAnalyzer
二分法分詞:CJKAnglyzer,只能分兩個字
詞庫分詞:按照某種算法構造詞mmanalyzer,ikanalyzer
使用庖丁分詞的步驟:(經常用於中文檢索)
1:引入jar包
2:ikanalyzer.cfg.xml配置文件,用戶在這裏可以配置自己的擴展字典,如果配置多個文件的話,用分號分開
3:引入文件,存放停用詞
文字高亮:
創建一個高亮器:
1:導入相應jar包
2:創建高亮器對象highlighter(參數1:格式化formatter,參數2:碎片scorer)
3:設置高亮,生成一段摘要,摘要的大小默認爲100個字
相關度排序:
boost:得分,sort:排序
得分與檢索的文本的內容有關係
設置相關度的,參數:2f:表示原文本得分的2倍
sortfield:表示針對哪個字段進行排序,參數1:針對的字段,參數2:表示按照排列的數據類型
使用sortfield提供的靜態方法即可獲取
如果使用sort進行排列,得分將失去效果,參數3:表示對字段的排序,true:表示降序,false:升序
默認爲升序
string和int類型在比較排序的時候不同eg:
過濾器:
範圍進行過濾:參數1:過濾的字段,設置查詢字段的最小值,設置查詢字段的最大值,是否包含最小值,true包含最小值,false不包含最小值;是否包含最大值,true包含最大值,false不包含最大值
查詢:
只針對一個或多個字段進行查詢
範圍查詢:numericrangequery
關鍵詞查詢:termquery
通配符查詢:wildcardquery:?表示一個字符,*表示多個字符
查詢所有:mathalldocsquery
模糊查詢:fuzzyquery,0.8F表示最小相似度
短語查詢:phrasequery,query.add(參數1:表示titile字段的值,參數2:指定title字段的值出現的位置,位置從0開始)
setslope:表示兩個詞最大的間隔不超過n
布爾查詢:booleanquery
compass:對lucene的封裝,類似於hibernate
1:導入jar包
2:在src下建一個compass.cfg.xml
配置索引庫的目錄,導入映射配置,其他配置
compass API:
CompassConfiguration cfg = new CompassConfiguration().configure(); // compass.cfg.xml
Compass sf = cfg.buildCompass();
CompassSession session = sf.openSession();
CompassTransaction tx = session.beginTransaction();
session.xxxxxx(); // 操作
tx.commit();
session.close();

CompassSession
 create(obj)  建立索引
 save(obj)  保存索引(建立或更新索引)
 delete(class, id) 刪除索引
 get/load(..)
 find(String).. 查詢
主配置文件 compass.cfg.xml
 1,索引庫信息(目錄)
 2,導入映射配置
 3,其他配置(分詞器、高亮器...)

映射配置
  * 類 -- Document
  * 屬性 -- Field
<?xml version="1.0" encoding="UTF-8"?>
<compass-core-config xmlns="http://www.compass-project.org/schema/core-config"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.compass-project.org/schema/core-config
http://www.compass-project.org/schema/compass-core-config-2.2.xsd">

 <compass name="default">
  <!-- 配置索引庫的目錄 -->
  <connection>
   <file path="./indexDir/" />
  </connection>

  <!-- 導入映射配置 -->
  <mappings>
   <class name="cn.itcast.compassTest.Article" />
  </mappings>
  <!--
      其它配置 
      -->
  <settings>
   <!--   設置高亮器,返回摘要的大小,默認是返回100個詞      -->
   <setting name="compass.engine.highlighter.default.fragmenter.simple.size"
    value="20" />
   <!--   生成html的前綴,默認值<b>,<font color='red'>      -->
   <setting name="compass.engine.highlighter.default.formatter.simple.pre"
    value="&lt;font color='red'&gt;" />
   <!-- 生成html的後綴,默認值</b>,</font>      -->
   <setting name="compass.engine.highlighter.default.formatter.simple.post"
    value="&lt;/font&gt;" />
   <!-- 分詞器,使用極易分詞      -->
   <setting name="compass.engine.analyzer.default.type" value="jeasy.analysis.MMAnalyzer" />
  </settings>


 </compass>
</compass-core-config>   
bean文件:
package cn.itcast.compassTest;

import org.compass.annotations.Index;
import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableBoostProperty;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.annotations.Store;
@Searchable
public class Article {
 //format,使用0補全id的字段值,字符串之間的比較:使用補零算法
 @SearchableId(name="id",format="00000000")
 private Integer id;
 @SearchableProperty(name="title",store=Store.YES,index=Index.ANALYZED)
 private String title;
 @SearchableProperty(name="content",store=Store.YES,index=Index.ANALYZED)
 private String content;
 //設置相關度得分,默認值是1F
 @SearchableBoostProperty
 private float boostValue = 1F;

 public float getBoostValue() {
  return boostValue;
 }
 public void setBoostValue(float boostValue) {
  this.boostValue = boostValue;
 }
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }} 
//創建索引庫
 public void createIndex(Article article){
  CompassSession session = CompassUtils.getSession();
  CompassTransaction tr = session.beginTransaction();
  try {
   session.create(article);
   tr.commit();
  } catch (Exception e) {
   tr.rollback();
   e.printStackTrace();
  } finally{
   session.close();
  }
 }
//查詢索引庫(支持分頁)
 public ResultBean<Article> searchIndex(String queryString,int firstResult,int maxResult){
  CompassSession session = CompassUtils.getSession();
  CompassTransaction tr = session.beginTransaction();
  int count = 0;
  List<Article> list = new ArrayList<Article>();
  try {
   CompassHits hits = session.find(queryString);
   count = hits.length();//獲取總的記錄數
   int endResult = Math.min(firstResult+maxResult, count);
   for(int i=firstResult;i<endResult;i++){
    System.out.println("得分:"+hits.score(i));
    Article article = (Article) hits.data(i);
    list.add(article);
   }
   tr.commit();
  } catch (Exception e) {
   tr.rollback();
   e.printStackTrace();
  } finally{
   session.close();
  }
  return new ResultBean<Article>(count,list);
 }
/*設置高亮
    * 針對數據的content字段設置高亮的效果
    * 如果文本中存在高亮的效果,返回高亮後的值,否則返回null
*/   
   String text=hits.highlighter(i).fragment("content");
   System.out.println("高亮後的效果"+text);
   if(text!=null){
    article.setContent(text);
   }
/*CompassQuery query=session.queryBuilder().queryString(queryString).toQuery();
  query.addSort("id", SortDirection.REVERSE);//按照id的降序排列
*/  //過濾
  /*CompassQueryFilter filter=session.queryFilterBuilder().between("id", 5, 15, true, true);
  query.setFilter(filter);*/

使用短語查詢:
/使用短語查詢
 CompassQuery query6=session.queryBuilder().multiPhrase("title")
 .add("lucene")
 .add("框架")
 .setSlop(5)
 .toQuery()
使用布爾查詢:三種組合形式
  //第一種組合,Must和Must,相當於and,求交集
//第二種組合,MustNot和Must,相當於非+and
//第三種組合,Should和Should,相當於or,求並集
//使用布爾查詢,三種組合形式
 CompassQuery query7=session.queryBuilder().bool().addMust(query).addMust(query2).toQuery();
 CompassQuery query8=session.queryBuilder().bool().addMustNot(query).addMust(query2).toQuery();
 CompassQuery query9=session.queryBuilder().bool().addShould(query).addShould(query2).toQuery();

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章