lucene框架全文檢索搜索引擎方案

搜索引擎技術方案數據庫

  1. 搜索引擎方案
  • 功能需求背景:

----有搜索引擎需求服務器

 

  • 功能需求
  1. 提升查詢效率,關鍵詞全文檢索。
  2. 不須要訪問屢次數據庫,只能一次數據庫查詢。
  3. 準確關鍵詞全文檢索。
  4. 因爲查詢功能效率較差,等待時間過長,數據量大以及多租戶多用戶關係查詢。

 

  • 需求分析
  1. 提升用戶體驗,查詢效率,關鍵詞全文檢索。
  2. 準確性查找關鍵詞全文檢索數據,不使用模糊查詢。
  3. 多租戶與用戶關係:多對多,多對一,一對多。
  4. 根據多租戶與用戶關係來關鍵詞全文檢索。

 

  • 解決方案(建議使用lucene框架搜索引擎)

方案一:(推薦)框架

  1. 第一步:定義一個租戶標識做爲索引庫(即服務器盤符文件夾路徑)。
  2. 第二步:dataId+用戶標識=idField(索引庫id)。
  3. 第三步:指定檢索字段拼接於nameField(索引庫name)
  4. 第四步:對索引庫增刪改。
  5. 第五步:全文檢索出該租戶下全部符合的關鍵詞檢索(能夠設置檢索的前幾條)。
  6. 第六步:經過用戶標識過濾用戶數據,從idField(索引庫id)解析dataId保存數據集。
  7. 第七步:經過dataId數據集去數據庫查找對應數據(id查詢結果集)。
  8. 第八步:查詢結果集返回頁面查詢。

 

方案二:搜索引擎

  1. 第一步:定義一個索引庫(即服務器盤符文件夾路徑)。
  2. 第二步:租戶標識+dataId+用戶標識=idField(索引庫id)。
  3. 第三步:指定檢索字段拼接於nameField(索引庫name)
  4. 第四步:對索引庫增刪改。
  5. 第五步:全文檢索出該租戶下全部符合的關鍵詞檢索(能夠設置檢索的前幾條)。
  6. 第六步:經過租戶標識過濾租戶數據,經過用戶標識過濾用戶數據,從idField(索引庫id)解析dataId保存數據集。
  7. 第七步:經過dataId數據集去數據庫查找對應數據(id查詢結果集)。
  8. 第八步:查詢結果集返回頁面查詢。

 

  1. Lucene索引結構圖解

  1. Lucene全文檢索說明
  1. 索引庫的增、刪、改是由indexWriter來操做的
  2. 同一個時刻內。同一個索引庫,僅僅能贊成一個indexWriter操做
  3. 當IndexWriter建立完畢之後,indexwriter所指向的索引庫就被佔據了。僅僅有當indexWriter.close時。才幹釋放鎖的資源
  4. 當一個新的indexWriter想擁有索引庫時,原來的indexWriter必須釋放鎖
  5. 僅僅要索引庫中存在write.lock文件,說明上鎖了
  6. indexWriter.close有兩層含義:1. 關閉IO資源; 2.釋放鎖
  7. 可以設置很是多個索引庫.
  8. 索引庫能不能合併起來?

        假設是內存索引庫對象

        Directory ramDirectory = new RamDirectory(Directory d);blog

        這樣就可以把一個索引庫放入到內存索引庫中索引

        利用IndexWriter.addIndexesNoOptimize方法可以把很是多個索引庫進行合併操做.內存

  1. 應用程序能不能在內存中和索引庫進行交互.
  1. 搜索引擎實現
  1. 索引庫寫入信息

public void testCreateIndex() throws Exception{資源

/**get

* 一、建立一個student對象,並且把信息存放進去

* 二、調用indexWriter的API把數據存放在索引庫中

* 三、關閉indexWriter

*/

// 建立一個Student對象。並且把信息存放進去

Student student = new Student();

student.setId(1L);

student.setName("張三");

// 調用indexWriter的API把數據存放在索引庫中

  /**

* 建立一個IndexWriter

*    參數三個 一、索引庫, 指向索引庫的位置  二、分詞器

*/

// 建立索引庫

Directory directory = FSDirectory.open(new File("./indexDir"));

// 建立分詞器

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);

IndexWriter indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED);

// 把一個student對象轉化成document

Document document = new Document();

Field idField = new Field("id",student.getId().toString(),Store.YES,Index.NOT_ANALYZED);

Field nameField = new Field("name",student.getName(),Store.YES,Index.ANALYZED);

document.add(idField);

document.add(nameField);

indexWriter.addDocument(document);

// 關閉indexWriter

indexWriter.close();

}

  1. 索引庫讀取信息

public void testSearchIndex() throws Exception{

/**

* 一、建立一個IndexSearch對象

* 二、調用search方法進行檢索

* 三、輸出內容

*/

// 建立一個 IndexSearch對象

Directory directory = FSDirectory.open(new File("./indexDir"));

IndexSearcher indexSearcher = new IndexSearcher(directory);

// 調用search方法進行檢索

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);

QueryParser queryParser = new QueryParser(Version.LUCENE_30,"name",analyzer);

Query query = queryParser.parse("張");  // 要查找的關鍵詞

TopDocs topDocs = indexSearcher.search(query, 2);  // 前兩條

int count = topDocs.totalHits;  // 依據關鍵詞查詢出來的總的記錄數

ScoreDoc[] scoreDocs = topDocs.scoreDocs;

List<Student> studentList = new ArrayList<Student>();

for(ScoreDoc scoreDoc:scoreDocs){

float score = scoreDoc.score;  // 關鍵詞得分

int index = scoreDoc.doc;  // 索引的下標

Document document = indexSearcher.doc(index);

// 把document轉化成Student

Student student = new  Student();

student.setId(Long.parseLong(document.get("id")));  // document.getField("id").stringValue()

student.setTitle(document.get("name"));

studentList.add(student);

}

 

for(Student student:studentList){

System.out.println(student.getId());

System.out.println(student.getName());

}

}

相關文章
相關標籤/搜索