1.Solr的簡介
Solr是一個獨立的企業級搜索應用服務器,它對外提供類似於Web-service的API接口。用戶可以通過http請求,向搜索引擎服務器提交一定格式的XML文件,生成索引;也可以通過Http Get操作提出查找請求,並得到XML格式的返回結果。
2.工作原理
solr是基於Lucence開發的企業級搜索引擎技術,而lucence的原理是倒排索引。那么什么是倒排索引呢?接下來我們就介紹一下lucence倒排索引原理。
假設有兩篇文章1和2:
文章1的內容為:老超在卡子門工作,我也是。
文章2的內容為:小超在鼓樓工作。
由於lucence是基於關鍵詞索引查詢的,那我們首先要取得這兩篇文章的關鍵詞。如果我們把文章看成一個字符串,我們需要取得字符串中的所有單詞,即分詞。分詞時,忽略”在“、”的“之類的沒有意義的介詞,以及標點符號可以過濾。
我們使用Ik Analyzer實現中文分詞,分詞之后結果為:
文章1:
文章2:
接下來,有了關鍵詞后,我們就可以建立倒排索引了。上面的對應關系是:“文章號”對“文章中所有關鍵詞”。倒排索引把這個關系倒過來,變成: “關鍵詞”對“擁有該關鍵詞的所有文章號”。
通常僅知道關鍵詞在哪些文章中出現還不夠,我們還需要知道關鍵詞在文章中出現次數和出現的位置,通常有兩種位置:
a.字符位置,即記錄該詞是文章中第幾個字符(優點是關鍵詞亮顯時定位快);
b.關鍵詞位置,即記錄該詞是文章中第幾個關鍵詞(優點是節約索引空間、詞組(phase)查詢快),lucene中記錄的就是這種位置。
加上出現頻率和出現位置信息后,我們的索引結構變為:
實現時,lucene將上面三列分別作為詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不僅保存有每個關鍵詞,還保留了指向頻率文件和位置文件的指針,通過指針可以找到該關鍵字的頻率信息和位置信息。
3.使用SolrJ管理索引庫
使用SolrJ可以實現索引庫的增刪改查操作。
3.1 添加文檔
第一步:把solrJ的jar包添加到工程中。
第二步:創建一個SolrServer,使用HttpSolrServer創建對象。
第三步:創建一個文檔對象SolrInputDocument對象。
第四步:向文檔中添加域。必須有id域,域的名稱必須在schema.xml中定義。
第五步:把文檔添加到索引庫中。
第六步:提交。
public voidtestSolrJAdd() throws SolrServerException, IOException { // 創建一個SolrServer對象。創建一個HttpSolrServer對象 // 需要指定solr服務的url SolrServer solrServer = newHttpSolrServer( "http://101.132.69.111:8080/solr/collection1"); // 創建一個文檔對象SolrInputDocument SolrInputDocument document= newSolrInputDocument(); // 向文檔中添加域,必須有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刪除的方法。
第三步:提交。
publicvoiddeleteDocumentById()throwsException { SolrServer solrServer = newHttpSolrServer( "http://101.132.69.111:8080/solr/collection1"); solrServer.deleteById( "123"); // 提交 solrServer.commit(); }
3.2.2 根據查詢刪除
publicvoiddeleteDocumentByQuery()throwsException { SolrServer solrServer = newHttpSolrServer( "http://101.132.69.111:8080/solr/collection1"); //這邊會根據分詞去刪 solrServer.deleteByQuery( "item_title:紅米手機"); solrServer.commit(); }
3.3 查詢索引庫
第一步:創建一個SolrServer對象
第二步:創建一個SolrQuery對象。
第三步:向SolrQuery中添加查詢條件、過濾條件。
第四步:執行查詢。得到一個Response對象。
第五步:取查詢結果。
第六步:遍歷結果並打印。
3.3.1 簡單查詢
publicvoidqueryDocument() throws Exception { // 第一步:創建一個SolrServer對象 SolrServer solrServer = newHttpSolrServer( "http://101.132.69.111:8080/solr/collection1"); // 第二步:創建一個SolrQuery對象。 SolrQuery query = newSolrQuery(); // 第三步:向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 帶高亮顯示
public voidsearchDocumet() throws Exception { // 創建一個SolrServer對象 SolrServer solrServer = newHttpSolrServer( "http://101.132.69.111:8080/solr/collection1"); // 創建一個SolrQuery對象 SolrQuery query = newSolrQuery(); // 設置查詢條件、過濾條件、分頁條件、排序條件、高亮 // 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"); StringitemTitle = ""; if(list != null&& list.size() > 0) { itemTitle = list. get( 0); } else{ 36itemTitle = ( 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")); }
4.Solr服務器中的后台數據處理
這個其實是通過圖形界面操作,只需手動填寫查詢條件,不需要進行代碼處理。但是實際項目開發中,還是需要進行代碼編寫的。
solr的基礎語法
1.q 查詢的關鍵字,此參數最為重要,例如,q= id: 1,默認為q=*:*,
2.fq (filter query)過慮查詢,提供一個可選的篩選器查詢。返回在q查詢符合結果中同時符合的fq條件的查詢結果
3.sort 排序方式,例如 iddesc 表示按照 “ id” 降序
4.start 返回結果的第幾條記錄開始,一般分頁用,默認 0開始
5.rows 指定返回結果最多有多少條記錄,默認值為 10,配合start實現分頁
6.fl 指定返回哪些字段,用逗號或空格分隔,注意:字段區分大小寫,例如fl= id,title,sort
7.df 默認的查詢字段,一般默認指定
8.wt (writer type)指定輸出格式,有 xml, json, php等
9.indent 返回的結果是否縮進,默認關閉0
10.hl 高亮
10.1.hl.fl 設定高亮顯示的字段
10.2.hl.requireFieldMatch 如果置為 true,除非用hl.fl指定了該字段,查詢結果才會被高亮。它的默認值是 false。
10.3.hl.usePhraseHighlighter 如果一個查詢中含有短語(引號框起來的)那么會保證一定要完全匹配短語的才會被高亮。
10.4.hl.highlightMultiTerm如果使用通配符和模糊搜索,那么會確保與通配符匹配的term會高亮。默認為 false,同時hl.usePhraseHighlighter要為 true。
10.5.hl.fragsize 返回的最大字符數。默認是 100.如果為 0,那么該字段不會被fragmented且整個字段的值會被返回。