Solr
運行Solr服務
方式一:Jetty服務器啟動Solr
- 進入solr-4.10.2/example目錄
- 打開命令行,執行java –jar start.jar命令,即可啟動Solr服務
- 打開瀏覽器,通過http://localhost:8983/solr來訪問Solr管理頁面。
方式二:Tomcat服務器啟動Solr
- 部署Web服務,將solr-4.10.2/example/webapps/solr.war復制到自己的tomcat/webapps目錄中,並解壓,然后刪除solr.war文件
- 在Tomcat中加入相關jar包:將“resource\solr在tomcat運行需要導入的jar包\lib”下的jar包復制tomcat/webapps/solr/WEB-INF/lib下。
並且把class/log4j.properties復制到tomcat/webapps/solr/WEB-INF下 - 修改Tomcat配置文件,指向Solr的索引庫及配置目錄。
注意,這里可以指向solr-4.10.2/example/solr目錄,如果想獨立出來,也可以將這個solr文件夾復制出來到任意位置(不要出現中文),例如:例如:C:/tmp/solr - 進入Tomcat文件夾,用記事本打開:tomcat/bin/catalina.bat文件,添加一條配置信息,指向我們的索引庫及配置目錄:set "JAVA_OPTS=-Dsolr.solr.home=C:/tmp/solr"
- 進入tomcat/bin目錄,雙擊 startup.bat文件啟動服務器
- 打開瀏覽器,訪問http://localhost:8080/solr 進入Solr管理頁面
Solr管理頁面
Dashboard儀表盤
顯示solr服務及系統運行信息
Logging(日志)
solr運行的日志信息
Core Admin(Core管理)
在Solr中,每一個Core,代表一個索引庫,里面包含索引數據及其配置信息。
Solr中可以擁有多個Core,也就同時管理多個索引庫!就像在MySQL中可以有多個database一樣!
JavaProperties
Java運行環境信息
ThreadDump
solr運行線程信息
CoreSelector(Core選擇器)
schema.xml
注意:在本文件中,有兩個字段是Solr自帶的字段,絕對不要刪除:_version_節點和_root_節點
Field字段定義字段的屬性信息段
屬性及含義:
name:字段名稱,最好以下划線或者字母開頭
type:字段類型,指向的是本文件中的
indexed:是否創建索引
stored:是否被存儲
multiValued:是否可以有多個值,如果字段可以有多個值,設置為true
FieldType指定數據類型
屬性及含義:
name:字段類型的名稱,可以自定義,
class:字段類型在Solr中的類。StrField可索引不可分詞。TextField字段可索引,可以分詞,所以需要指定分詞器
唯一主鍵
id
Lucene中本來是沒有主鍵的。刪除和修改都需要根據詞條進行匹配。而Solr卻可以設置一個字段為唯一主鍵,這樣刪改操作都可以根據主鍵來進行!
IK分詞器
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
SolrJ的使用
添加或修改索引庫數據
private static String baseURL = "http://localhost:8080/solr/core1";
@Test
public void createTest() throws Exception {
//連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
//創建文檔對象
SolrInputDocument document = new SolrInputDocument();
document.addField("id", "5");
document.addField("title", "8848手機,鈦合金外殼,注定不平凡");
document.addField("content", "8848發發發");
//向solr服務器寫入文檔
solrServer.add(document);
solrServer.commit();
}
@Test
public void create2Test() throws Exception {
//連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
//創建文檔對象
Item item = new Item();
item.setId("6");
item.setTitle("金立M2017成功人士的標配");
item.setContent("金立你值得擁有");
//向solr服務器寫入文檔
solrServer.addBean(item);
solrServer.commit();
}
//添加@Field注解
public class Item{
@Field
private String id;
@Field
private String title;
@Field
private String content;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
刪除索引庫數據
@Test
public void deleteTest() throws SolrServerException, IOException {
// 連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
// 刪除索引
//solrServer.deleteById("6");
solrServer.deleteByQuery("title:金立");
// 提交
solrServer.commit();
}
查詢索引庫數據
在創建SolrQuery時,我們填寫的Query語句,可以有以下高級寫法:
- 通配符?和 *:“*”表示匹配任意字符;“?”表示匹配出現的位置
- 布爾操作:AND、OR和NOT布爾操作(推薦使用大寫,區分普通字段)
- 子表達式查詢(子查詢):可以使用“()”構造子查詢。比如:(query1 AND query2) OR (query3 AND query4)
- 相似度查詢:指定編輯距離的相似度查詢:對模糊查詢可以設置編輯距離,可選0-2的整數(默認為2):title:appla~1。
- 范圍查詢(Range Query):Lucene支持對數字、日期甚至文本的范圍查詢,並且兩端范圍。結束的范圍可以使用“*”通配符。
(1)日期范圍(ISO-8601時間GMT):a_begin_date:[1990-01-01T00:00:00.000Z TO 1999-12-31T24:59:99.999Z]
(2)數字:salary:[2000 TO *]
(3)文本:entryNm:[a TO a]
@Test
public void queryTest() throws SolrServerException{
// 連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
//創建查詢條件對象
SolrQuery params = new SolrQuery("*:*");
//執行查詢,獲取響應數據
QueryResponse response = solrServer.query(params);
//獲取數據結果集
SolrDocumentList list = response.getResults();
System.out.println("一共獲取了" + list.size()+"條結果:");
for (SolrDocument solrDocument : list) {
System.out.println("id: " + solrDocument.getFieldValue("id"));
System.out.println("title:" + solrDocument.getFieldValue("title"));
}
}
@Test
public void queryBeanTest() throws SolrServerException{
// 連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
//創建查詢條件對象
SolrQuery params = new SolrQuery("*:*");
//執行查詢,獲取響應
QueryResponse response = solrServer.query(params);
List<Item> beans = response.getBeans(Item.class);
System.out.println("一共獲取了" + beans.size()+"條結果:");
for (Item item : beans) {
System.out.println("id: " + item.getId());
System.out.println("title:" + item.getTitle());
}
}
實現排序
@Test
public void querySortTest() throws SolrServerException, IOException {
// 連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
// 創建查詢條件對象,范圍查詢,包含兩端
SolrQuery query = new SolrQuery("*:*");
// 設置查詢的排序參數,1-排序的字段名,2-排序方式(ORDER:asc desc)
query.setSort("id", ORDER.asc);
// 執行查詢,獲取響應數據
QueryResponse response = solrServer.query(query);
// 獲取結果集數據
List<Item> list = response.getBeans(Item.class);
System.out.println("總記錄數 numFound:"+response.getResults().getNumFound());
for (Item item : list) {
System.out.println("id: " + item.getId());
System.out.println("title:" + item.getTitle());
}
}
實現分頁
@Test
public void queryPageTest() throws SolrServerException, IOException {
// 准備分頁參數
int pageNum = 1; //頁碼
int pageSize = 2; //每頁條數
// 連接solr服務器
HttpSolrServer solrServer = new HttpSolrServer(baseURL);
// 創建查詢條件對象
SolrQuery params = new SolrQuery("*:*");
// 設置查詢的排序參數,1-排序的字段名,2-排序方式(ORDER:asc desc)
params.setStart((pageNum-1)*pageSize);//設置起始條數
params.setRows(pageSize);//設置每頁條數
// 執行查詢,獲取響應數據
QueryResponse response = solrServer.query(params);
// 獲取結果集數據
SolrDocumentList list = response.getResults();
System.out.println("一共獲取了" + list.size() + "條結果:");
for (SolrDocument solrDocument : list) {
System.out.println("id: " + solrDocument.getFieldValue("id"));
System.out.println("title:" + solrDocument.getFieldValue("title"));
}
}
實現高亮
@Test
public void highLightingTest() throws SolrServerException, IOException{
// 初始化solrj服務
HttpSolrServer server = new HttpSolrServer(baseURL);
// 設置查詢條件
SolrQuery params = new SolrQuery("title:手機");
// 設置前置標簽
params.setHighlightSimplePre("<em >");
// 設置后置標簽
params.setHighlightSimplePost("</em>");
// 添加高亮字段
params.addHighlightField("title");
// 執行查詢
QueryResponse queryResponse = server.query(params);
// 外層的Map,key:id,value:id以外的其他高亮字段,可能有多個,也是一個Map
// 內層的Map,key:高亮字段的名稱,value:字段的內容,集合
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
// 遍歷map,獲取結果
Set<String> ids = highlighting.keySet();
for (String id : ids) {
System.out.println("id: " + id);;
// 獲取高亮字段的集合
Map<String, List<String>> map = highlighting.get(id);
// 獲取高亮字段
System.out.println(map.get("title").get(0));
// 因為content不是高亮字段,所以打印出的內容為null
System.out.println(map.get("content"));
}
}