Solr的工做原理以及如何管理索引庫

1. Solr的簡介

​ Solr是一個獨立的企業級搜索應用服務器,它對外提供相似於Web-service的API接口。用戶能夠經過http請求,向搜索引擎服務器提交必定格式的XML文件,生成索引;也能夠經過Http Get操做提出查找請求,並獲得XML格式的返回結果。php

​ Solr是Apache軟件基金會下的子項目之一。
Solr的工做原理以及如何管理索引庫java

2. 工做原理

​ solr是基於Lucence開發的企業級搜索引擎技術,而lucence的原理是倒排索引。那麼什麼是倒排索引呢?接下來咱們就介紹一下lucence倒排索引原理。json

假設有兩篇文章1和2:服務器

文章1的內容爲:老超在卡子門工做,我也是。ide

文章2的內容爲:小超在鼓樓工做。ui

因爲lucence是基於關鍵詞索引查詢的,那咱們首先要取得這兩篇文章的關鍵詞。若是咱們把文章當作一個字符串,咱們須要取得字符串中的全部單詞,即分詞。分詞時,忽略」在「、」的「之類的沒有意義的介詞,以及標點符號能夠過濾。搜索引擎

咱們使用Ik Analyzer實現中文分詞,分詞以後結果爲:url

文章1:
Solr的工做原理以及如何管理索引庫指針

文章2:
Solr的工做原理以及如何管理索引庫code

接下來,有了關鍵詞後,咱們就能夠創建倒排索引了。上面的對應關係是:「文章號」對「文章中全部關鍵詞」。倒排索引把這個關係倒過來,變成: 「關鍵詞」對「擁有該關鍵詞的全部文章號」。

文章一、文章2通過倒排後變成:

Solr的工做原理以及如何管理索引庫

一般僅知道關鍵詞在哪些文章中出現還不夠,咱們還須要知道關鍵詞在文章中出現次數和出現的位置,一般有兩種位置:

a.字符位置,即記錄該詞是文章中第幾個字符(優勢是關鍵詞亮顯時定位快);

b.關鍵詞位置,即記錄該詞是文章中第幾個關鍵詞(優勢是節約索引空間、詞組(phase)查詢快),lucene中記錄的就是這種位置。

加上出現頻率和出現位置信息後,咱們的索引結構變爲:

Solr的工做原理以及如何管理索引庫

實現時,lucene將上面三列分別做爲詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不只保存有每一個關鍵詞,還保留了指向頻率文件和位置文件的指針,經過指針能夠找到該關鍵字的頻率信息和位置信息。

3. 使用SolrJ管理索引庫

使用SolrJ能夠實現索引庫的增刪改查操做。

3.1 添加文檔

第一步:把solrJ的jar包添加到工程中。

第二步:建立一個SolrServer,使用HttpSolrServer建立對象。

第三步:建立一個文檔對象SolrInputDocument對象。

第四步:向文檔中添加域。必須有id域,域的名稱必須在schema.xml中定義。

第五步:把文檔添加到索引庫中。

第六步:提交。

@Test
public void testSolrJAdd() throws SolrServerException, IOException {
  // 建立一個SolrServer對象。建立一個HttpSolrServer對象
  // 須要指定solr服務的url
  SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1");
  // 建立一個文檔對象SolrInputDocument
  SolrInputDocument document = new SolrInputDocument();
  // 向文檔中添加域,必須有id域,域的名稱必須在schema.xml中定義
  document.addField("id", "123");
  document.addField("item_title", "紅米手機");
  document.addField("item_price", 1000);
  // 把文檔對象寫入索引庫
  solrServer.add(document);
  // 提交
  solrServer.commit();
}

3.2 刪除文檔

3.2.1 根據id刪除

第一步:建立一個SolrServer對象。

第二步:調用SolrServer對象的根據id刪除的方法。

第三步:提交。

@Test
public void deleteDocumentById() throws Exception {
  SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1");
  solrServer.deleteById("123");
  // 提交
  solrServer.commit();
}

3.2.2 根據查詢刪除

@Test
public void deleteDocumentByQuery() throws Exception {
  SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1");
  //這邊會根據分詞去刪
  solrServer.deleteByQuery("item_title:紅米手機");
  solrServer.commit();
}

3.3 查詢索引庫

第一步:建立一個SolrServer對象

第二步:建立一個SolrQuery對象。

3 向SolrQuery中添加查詢條件、過濾條件。。。

第四步:執行查詢。獲得一個Response對象。

5 取查詢結果。

第六步:遍歷結果並打印。

3.3.1 簡單查詢

@Test
public void queryDocument() throws Exception {
    // 第一步:建立一個SolrServer對象
    SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1");
    // 第二步:建立一個SolrQuery對象。
    SolrQuery query = new SolrQuery();
    // 第三步:向SolrQuery中添加查詢條件、過濾條件。。。
    query.setQuery("*:*");
    // 第四步:執行查詢。獲得一個Response對象。
    QueryResponse response = solrServer.query(query);
    // 第五步:取查詢結果。
    SolrDocumentList solrDocumentList = response.getResults();
    System.out.println("查詢結果的總記錄數:" + solrDocumentList.getNumFound());
    // 第六步:遍歷結果並打印。
    for (SolrDocument solrDocument : solrDocumentList) {
      System.out.println(solrDocument.get("id"));
      System.out.println(solrDocument.get("item_title"));
      System.out.println(solrDocument.get("item_price"));
    }
}

3.3.2 帶高亮顯示

@Test
public void searchDocumet() throws Exception {
  // 建立一個SolrServer對象
  SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1");
  // 建立一個SolrQuery對象
  SolrQuery query = new SolrQuery();
  // 設置查詢條件、過濾條件、分頁條件、排序條件、高亮
  // query.set("q", "*:*");
  query.setQuery("手機");
  // 分頁條件
  query.setStart(0);
  query.setRows(30);
  // 設置默認搜索域
  query.set("df", "item_keywords");
  // 設置高亮
  query.setHighlight(true);
  // 高亮顯示的域
  query.addHighlightField("item_title");
  query.setHighlightSimplePre("<div>");
  query.setHighlightSimplePost("</div>");
  // 執行查詢,獲得一個Response對象
  QueryResponse response = solrServer.query(query);
  // 取查詢結果
  SolrDocumentList solrDocumentList = response.getResults();
  // 取查詢結果總記錄數
  System.out.println("查詢結果總記錄數:" + solrDocumentList.getNumFound());
  for (SolrDocument solrDocument : solrDocumentList) {
    System.out.println(solrDocument.get("id"));
    // 取高亮顯示
    Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
    List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
    String itemTitle = "";
    if (list != null && list.size() > 0) {
      itemTitle = list.get(0);
    } else {
      itemTitle = (String) solrDocument.get("item_title");
    }
    System.out.println(itemTitle);
    System.out.println(solrDocument.get("item_sell_point"));
    System.out.println(solrDocument.get("item_price"));
    System.out.println(solrDocument.get("item_image"));
    System.out.println(solrDocument.get("item_category_name"));
    System.out.println("=============================================");
  }
}

4. Solr服務器中的後臺數據處理

​ 這個實際上是經過圖形界面操做,只需手動填寫查詢條件,不須要進行代碼處理。可是實際項目開發中,仍是須要進行代碼編寫的。
Solr的工做原理以及如何管理索引庫

4.1 solr的基礎語法

q  查詢的關鍵字,此參數最爲重要,例如,q=id:1,默認爲q=*:*,

fq  (filter query)過慮查詢,提供一個可選的篩選器查詢。
        返回在q查詢符合結果中同時符合的fq條件的查詢結果

sort  排序方式,例如id  desc 表示按照 「id」 降序

  
start  返回結果的第幾條記錄開始,通常分頁用,默認0開始

rows  指定返回結果最多有多少條記錄,默認值爲 10,配合start實現分頁

fl  指定返回哪些字段,用逗號或空格分隔,注意:字段區分大小寫,例如,fl= id,title,sort

df   默認的查詢字段,通常默認指定
  
wt  (writer type)指定輸出格式,有 xml, json, php等

indent   返回的結果是否縮進,默認關閉

hl 高亮
    hl.fl  設定高亮顯示的字段
    hl.requireFieldMatch   若是置爲true,除非用hl.fl指定了該字段,查詢結果纔會被高亮。它的默認值是false。

   hl.usePhraseHighlighter   若是一個查詢中含有短語(引號框起來的)那麼會保證必定要徹底匹配短語的纔會被高亮。

    hl.highlightMultiTerm若是使用通配符和模糊搜索,那麼會確保與通配符匹配的term會高亮。默認爲false,同時hl.usePhraseHighlighter要爲true。

    hl.fragsize   返回的最大字符數。默認是100.若是爲0,那麼該字段不會被fragmented且整個字段的值會被返回。
相關文章
相關標籤/搜索