Solr是一個獨立的企業級搜索應用服務器,它對外提供相似於Web-service的API接口。用戶能夠經過http請求,向搜索引擎服務器提交必定格式的XML文件,生成索引;也能夠經過Http Get操做提出查找請求,並獲得XML格式的返回結果。php
Solr是Apache軟件基金會下的子項目之一。
java
solr是基於Lucence開發的企業級搜索引擎技術,而lucence的原理是倒排索引。那麼什麼是倒排索引呢?接下來咱們就介紹一下lucence倒排索引原理。json
假設有兩篇文章1和2:服務器
文章1的內容爲:老超在卡子門工做,我也是。ide
文章2的內容爲:小超在鼓樓工做。ui
因爲lucence是基於關鍵詞索引查詢的,那咱們首先要取得這兩篇文章的關鍵詞。若是咱們把文章當作一個字符串,咱們須要取得字符串中的全部單詞,即分詞。分詞時,忽略」在「、」的「之類的沒有意義的介詞,以及標點符號能夠過濾。搜索引擎
咱們使用Ik Analyzer實現中文分詞,分詞以後結果爲:url
文章1:
指針
文章2:
code
接下來,有了關鍵詞後,咱們就能夠創建倒排索引了。上面的對應關係是:「文章號」對「文章中全部關鍵詞」。倒排索引把這個關係倒過來,變成: 「關鍵詞」對「擁有該關鍵詞的全部文章號」。
文章一、文章2通過倒排後變成:
一般僅知道關鍵詞在哪些文章中出現還不夠,咱們還須要知道關鍵詞在文章中出現次數和出現的位置,一般有兩種位置:
a.字符位置,即記錄該詞是文章中第幾個字符(優勢是關鍵詞亮顯時定位快);
b.關鍵詞位置,即記錄該詞是文章中第幾個關鍵詞(優勢是節約索引空間、詞組(phase)查詢快),lucene中記錄的就是這種位置。
加上出現頻率和出現位置信息後,咱們的索引結構變爲:
實現時,lucene將上面三列分別做爲詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不只保存有每一個關鍵詞,還保留了指向頻率文件和位置文件的指針,經過指針能夠找到該關鍵字的頻率信息和位置信息。
使用SolrJ能夠實現索引庫的增刪改查操做。
第一步:把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(); }
第一步:建立一個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(); }
@Test public void deleteDocumentByQuery() throws Exception { SolrServer solrServer = new HttpSolrServer("http://101.132.69.111:8080/solr/collection1"); //這邊會根據分詞去刪 solrServer.deleteByQuery("item_title:紅米手機"); solrServer.commit(); }
第一步:建立一個SolrServer對象
第二步:建立一個SolrQuery對象。
3 向SolrQuery中添加查詢條件、過濾條件。。。
第四步:執行查詢。獲得一個Response對象。
5 取查詢結果。
第六步:遍歷結果並打印。
@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")); } }
@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("============================================="); } }
這個實際上是經過圖形界面操做,只需手動填寫查詢條件,不須要進行代碼處理。可是實際項目開發中,仍是須要進行代碼編寫的。
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且整個字段的值會被返回。