solr
什麼是solr
solr是一個apache的全文檢索引擎系統, 就是個war包, 部署到Tomcat下就可以獨立運行, 我們使用它的客戶端工具包solrj來遠程調用solr服務器, 完成對索引庫的操作(對索引庫的添加修改刪除, 查詢),solr底層使用lucene編寫.
作用:
對於大數據量搜索或者是查詢, 速度非常快, 並且不會隨着數據量的增大而減緩查詢速度.主要應用於大型的互聯網項目中, 做大規模數據查詢.
solr同類型技術:
elasticsearch是solr的同類型技術, elasticsearch在搜索的時候速度比solr要快.但是使用起來比solr要複雜,企業中現在elasticsearch比較流行
全文檢索算法(倒排索引表算法):
- 使用場景: 大數據量搜索查詢, 例如: 京東, 天貓的搜索功能.
- 描述: 查詢前先將查詢的內容抽取出來組成文檔(document), 也就相當於字典的正文, 然後進行切分詞, 將切分出來的詞組成索引(index)相當於字段的目錄, 查詢的時候先查詢索引根據索引找文檔, 這個過程叫做全文檢索
- 總結: 和字典原理一樣.
- 優點: 查詢速度快, 並且不會隨着查詢的數據量增大而變慢, 查詢結果精確
缺點: 索引會額外佔用大量的磁盤空間.
順序掃描法:
- 使用場景: 數據庫中的like模糊查詢就是用的這種算法
- 描述: 拿着需要查詢的關鍵字, 到內容中逐字逐行的對比, 直到查詢內容結束
- 優點: 查詢準確
缺點: 查詢速度慢, 並且會隨着查詢內容量增大越來越慢.
切分詞: 將一句一句話, 切分成一個一個詞, 去掉停用詞(的, 地得, a,an,the等), 去掉空格和標點符號, 大寫字母全部轉成小寫字母.
solr部署步驟
1. 在/usr/local目錄下創建solr文件夾
2. 複製solr安裝包, ik分詞器包, tomcat包到這個目錄下, 並且解壓
3. 將solr/example/webapps/solr.war複製到tomcat/webapps目錄下
4. 啓動tomcat目的是對war包解壓, 解壓完成後關閉tomcat
5. 到tomcat/webapps目錄中刪除solr.war
6. 複製solr/example/lib/ext下的所有到 tomcat/webapps/solr/WEB-INf/lib目錄下
7. 複製solr/example/solr目錄到 /usr/loca/solr目錄下並且改名問solrhome
8. 配置solrhome的位置到tomcat/webapps/solr/WEB-INF/web.xml中
9. 啓動tomcat, 瀏覽器訪問http://服務器地址:端口/solr看到solr頁面後證明部署成功
什麼是solrhome
solrhome就是solr的家, 一個solr服務器只能有一個solrhome, 一個solrhome中可以有多個solr實例, 裏面的collection1文件夾就是默認的solr實例, 一個solrhome中可以同時有多個實例, 實例中有索引庫, 實例和實例之間是互相隔離的.
solr中添加實例
一、進入solrhome文件夾,然後拷貝collection1到collection2
二、編輯collection2中的core.properties中的值爲collection2
三、保存,重啓tomcat
solr中添加數據
注意:
- 域名要先定義後使用, 沒有定義的域名直接使用會報錯
ERROR: [doc=002] unknown field 'sadfasdfasdfasdf'
- solr中添加數據的時候必須有主鍵域id, 沒有會報錯
Document is missing mandatory uniqueKey field: id"
-
solr中沒有修改方法, 添加就是修改, 修改就是添加, 每次修改數據的時候, 都是根據id主鍵先去查詢,如果查到了, 將原有數據刪除, 將新數據添加進去, 這就是修改, 如果沒有根據id查詢到數據, 則直接添加, 就成了添加.
-
刪除(XML格式)
根據id刪除
<delete>
<query>id: 002</query>
</delete>
<commit/>
刪除所有:
<delete>
<query>*:*</query>
</delete>
<commit/>
域的分類
solr中域的作用:自定義域名和類型就是爲了保存數據庫表中一列一列的數據, 表中的列名要和索引庫的域名對應
solr中域的分類:
field普通域
: 大多數情況都可以用這個域來完成, 主要定義了域名和域的類型.
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
dynamicField動態域
: solr中域名要先定義後使用, 沒有定義就使用會報錯, 如果沒有定義的域名想使用可以模糊匹配動態域, 讓沒有定義的域名可以使用.
<dynamicField name="*_is" type="int" indexed="true" stored="true" multiValued="true"/>
uniqueKey主鍵域
: 在添加數據的時候必須有主鍵域, 沒有會報錯, 這個不用添加也不用修改, 就使用這個默認的域名id就可以.
<uniqueKey>id</uniqueKey>
copyField複製域
: 複製域中有source叫做源域, dest代表目標域, 在維護數據的時候, 源域中的內容會複製到目標域中一份, 從目標域中搜索, 就相當於從多個源域中搜索一樣.
<copyField source="cat" dest="text"/>
集成中文分詞器
ik中文分詞器:
作用: 有中文語義分析的效果, 對中文分詞效果好.
配置文件:
stopword.dic
停止詞典: 且分詞的時候, 凡是出現在停止詞典中的詞都會被過濾掉.ext.dic
擴展詞典: 凡是專有名詞都會放到這裏, 如果自然語義中不是一個詞, 放到這裏後solr切分詞的時候就會切分成一個詞.
一、集成
二、在schema.xml中添加一個自定義的fieldType,使用中文分析器。
<!-- IKAnalyzer-->
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
三、在schema.xml中添加field,指定field的type屬性爲text_ik
<!--IKAnalyzer Field-->
<field name="content_ik" type="text_ik" indexed="true" stored="true" />
四、重啓tomcat,測試
自定義業務域
創建數據庫表,添加數據,將有用的列名作爲域。
<!--product-->
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_price" type="float" indexed="true" stored="true"/>
<field name="product_description" type="text_ik" indexed="true" stored="false" />
<field name="product_picture" type="string" indexed="false" stored="true" />
<field name="product_catalog_name" type="string" indexed="true" stored="true" />
<field name="product_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="product_name" dest="product_keywords"/>
<copyField source="product_description" dest="product_keywords"/>
solrj
solrJ是solr官方推出的客戶端工具包, 將solrj的jar包放到我們項目中, 我們調用solrj中的api來遠程給solr服務器發送命令, solr服務器就可以完成對索引庫的操作(添加修改刪除查詢)
solr增刪改
添加jar包
增加(修改)、刪除
public class TestIndexManager {
@Test
public void testIndexCreateAndUpdate() throws Exception {
/**
* 創建solr服務器連接
* http://192.168.200.128:8080/solr 連接的是默認實例,即collection1
* http://192.168.200.128:8080/solr/collection2
*/
SolrServer solrServer = new HttpSolrServer("http://192.168.200.128:8080/solr");
//創建文檔對象
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id","001");
doc.addField("title","三國演義");
//添加或修改
solrServer.add(doc);
//提交
solrServer.commit();
}
@Test
public void testIndexDelete() throws Exception {
/**
* 創建solr服務器連接
* http://192.168.200.128:8080/solr 連接的是默認實例,即collection1
* http://192.168.200.128:8080/solr/collection2
*/
SolrServer solrServer = new HttpSolrServer("http://192.168.200.128:8080/solr");
/**
* 刪除一個
*/
//solrServer.deleteById("001");
/**
* 條件刪除:刪除所有
*/
solrServer.deleteByQuery("*:*");
//提交
solrServer.commit();
}
}
solr查詢
public class TestIndexSearch {
@Test
public void testIndexSearch() throws Exception {
/**
* 創建solr服務器連接
* http://192.168.200.128:8080/solr 連接的是默認實例,即collection1
* http://192.168.200.128:8080/solr/collection2
*/
SolrServer solrServer = new HttpSolrServer("http://192.168.200.128:8080/solr");
//創建查詢對象
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("*:*");
//查詢並返回相應
QueryResponse query = solrServer.query(solrQuery);
//從響應中獲取結果集
SolrDocumentList results = query.getResults();
System.out.println(results.getNumFound());
for (SolrDocument result : results) {
System.out.println(result.get("id"));
System.out.println(result.get("title"));
}
}
}