Solr簡介
Solr是采用Java開發,基于Lucene的全文檢索伺服器,同時對其進行了擴充,提供了比Lucene更為豐富的查詢語言,同時實作了可配置、可擴充并對查詢性能進行了優化,并且提供了一個完善的功能管理界面,是一款非常優秀的全文搜尋引擎。 Solr是一個獨立的企業級搜尋應用伺服器,它對外提供類似于Web-Service的API接口,使用者可以通過http請求,向搜尋引擎伺服器送出一定格式的XML檔案,生成索引,也可以通過Http G Solret操作提出查找請求,并得到XML格式的傳回結果。
Solr與Lucene的關系
Lucene是一套資訊檢索工具包,但是并不包含搜尋引擎系統,它包含了索引結構、讀寫索引工具、相關性工具、排序等功能,是以在使用Lucene時仍需要關注搜尋引擎系統,例如資料擷取、解析、分詞方面的東西。 solr是基于Lucene開發的,Solr主要是為了打造一款企業級的搜尋引擎系統,是以它更接近于常用的搜尋引擎系統(百度、搜狗),它是一個搜尋引擎服務,通過各種API可以讓我們的應用使用搜尋服務,而不需要将搜尋邏輯耦合在應用中。而且solr可以根據配置檔案定義資料解析的方式,更像是一個搜尋架構,它也支援主從、熱換庫操作,還添加了高亮、facet等搜尋引擎常見的功能支援。 Nutch是一款開源的Java實作的搜尋引擎,它提供了我們運作自己的搜尋引擎所需的全部工具。包括全文檢索和web爬蟲。常用來使用Nutch做爬蟲。
Solr的簡單搭建運作
Solr 下載下傳位址:http://archive.apache.org/dist/lucene/solr/ 下載下傳解壓後的目錄:
配置步驟: 1.解壓solr-4.7.0.zip到你想到存放的路徑,比如目前使用者根目錄/Users/liuxun/solr-4.7.0
2.cmd打開指令行視窗,進入/Users/liuxun/solr-4.7.0/example目錄
3.執行指令:java -jar start.jar
4.通過第三步以後,系統會啟動solr自帶的jetty伺服器,通過 http://localhost:8983/solr/便可通路solr。
此時,solr已成功啟動
操作界面說明:
等等還有查詢 界面使用并不麻煩
指令測試管理索引
(一) 建立索引 此時solr已安裝并啟動,但是還沒有索引,隻有建立好索引,搜尋才能有結果
1、指令進入/solr-4.6.0/example/exampledocs目錄
2、執行指令:java -jar post.jar solr.xml monitor.xml,此時你已成功送出了2個solr文檔
3、執行完第二步後,我們可以通過浏覽器通路:http://localhost:8983/solr/collection1/select?q=solr&wt=xml
如果你想導入更多的文檔,執行指令:java -jar post.jar *.xml
(二)更新索引 當重複執行指令:java -jar post.jar *.xml後,發現搜尋的結果沒有出現重複的資料,原因:example目錄下的schema.xml中指定了列id為uniqueKey(即:唯一),是以重複送出資料到索引庫時,id相同的資料會替換原來document中的資料。
如果想要得到重複的資料,可以通過修改exampledocs目錄下*.xml中id值的方式實作
(三)删除索引 1、執行命 令:
java -Ddata=args -Dcommit=false -jar post.jar “<delete><id>SP2514N</id></delete>”,可以删除id為 SP2514N的document
2、執行第一步後,再去搜尋發現搜尋結果中還有id為SP2514N的資料,其實不是第一步沒有删除成功,因為第一步的指令中-Dcommit=false,是以第一步的删除操作沒有送出到索引(index)中。
3、在沒有打開新的searcher之前,第一步删除資料會一直存在于搜尋結果中,是以我們可以強制打開一個新的searcher,執行指令:java -jar post.jar -
(四)查詢索引 solr通過http以get的方式進行搜尋資料,如:http://localhost:8983/solr/collection1/select?q=solr&wt=xml
q:查詢的關鍵詞(此時查詢的字段是solrconfig.xml中指定的預設查詢字段<str name=”df”>text</str>)
fl:搜尋結果傳回的字段
sort:排序
wt:搜尋結果傳回格式
q=video&fl=name,id (return only name and id fields)
q=video&fl=name,id,score (return relevancy score as well)
q=video&fl=*,score (return all stored fields, as well as relevancy score)
q=video&sort=price desc&fl=name,id,price (add sort specification: sort by price descending)
q=video&wt=json (return response in JSON format)
使用SolrJ與Solr伺服器互動
我們要使用Solr服務,可以直接使用urlconnecion按照規則去調用Solr服務的接口,如果是web應用除了可以使用URLConnection在背景調用外還可以使用AJAX技術(XmlHttpRequest)調用,但是需要自己封裝資料,解析資料,非常麻煩。 SolrJ提供了針對各種用戶端的API,可以省去這些繁瑣的步驟,面向API程式設計 直接與Solr伺服器進行互動。
SolrJ的簡介和使用:
solrj是solr的java用戶端,用于通路solr索引庫。
它提供了添加、删除、查詢、優化等功能。
Jar 包位置
解壓目錄:
它是內建到solr壓縮包裡的,解壓檔案後,有個目錄/dist/,裡面就存放了solrj所用到的jar( /dist/solrj-lib/*.jar和 /dist/*.jar),把這些所有的jar都添加到項目中的classpath就可以直接開發了。 Demo示例如下(以上傳GitHub https://github.com/LX1993728/SolrJ_java_Test) Product.java
public class Product {
//Field中的value要遵循核心中schema中<fields>的規則
@Field(value="id")
private String id;
@Field(value="name")
private String name;
@Field(value="description")
private String desc;
@Field(value="price")
private float price;
// setter getter
// ......
}
@Field 表示 目前屬性與索引庫中哪個已經聲明的字段名相對應 (具體規則由schema指定) SolrDao.java (索引的增删改查)
package liuxun.solrj.dao;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import liuxun.solrj.bean.Product;
/**
* 使用solrJ 向solr 送出請求,增删改查, solrJ 底層頁是發送http 協定...
*
* @author liuxun
*/
public class SolrDao {
// 在solr 當中有一些預設的字段和動态字段規則,配置在檔案/example/solr/collection1/conf/schema.xml
// 添加預設索引屬性
public void addDefaultField() throws SolrServerException, IOException {
// 聲明要連接配接solr伺服器的位址
String url = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(url);
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", "預設情況下必須添加的字段,用來區分文檔的唯一辨別");
doc.addField("name", "預設的名稱屬性字段");
doc.addField("description", "預設的表示描述資訊的字段");
solr.add(doc);
solr.commit();
}
// 添加動态索引屬性
public void addDynamicField() throws SolrServerException, IOException {
// 聲明要連接配接solr伺服器的位址
String url = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(url);
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", "adwweqwewe");
doc.addField("nam_s", "動态字段的StringField類型格式為*_s");
doc.addField("desc_s", "動态字段的TextField類型格式為*_t");
solr.add(doc);
solr.commit();
}
// 添加索引
public void addIndex(Product product) throws SolrServerException, IOException {
// 聲明要連接配接solr伺服器的位址
String url = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(url);
solr.addBean(product);
solr.commit();
}
// 更新索引
public void updateIndex(Product product) throws IOException, SolrServerException {
// 聲明要連接配接solr伺服器的位址
String url = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(url);
solr.addBean(product);
solr.commit();
}
// 删除索引
public void delIndex(String id) throws SolrServerException, IOException {
// 聲明要連接配接solr伺服器的位址
String url = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(url);
solr.deleteById(id);
// solr.deleteByQuery("id:*");
solr.commit();
}
// 查找索引
public void findIndex() throws SolrServerException {
// 聲明要連接配接solr伺服器的位址
String url = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(url);
// 查詢條件
SolrQuery solrParams = new SolrQuery();
solrParams.setStart(0);
solrParams.setRows(10);
solrParams.setQuery("name:蘋果 +description:全新4G");
// 開啟高亮
solrParams.setHighlight(true);
solrParams.setHighlightSimplePre("<font color='red'>");
solrParams.setHighlightSimplePost("</font>");
// 設定高亮的字段
solrParams.setParam("hl.fl", "name,description");
// SolrParams是SolrQuery的子類
QueryResponse queryResponse = solr.query(solrParams);
// (一)擷取查詢的結果集合
SolrDocumentList solrDocumentList = queryResponse.getResults();
// (二)擷取高亮的結果集
// 第一個Map的鍵是文檔的ID,第二個Map的鍵是高亮顯示的字段名
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println("=====" + solrDocument.toString());
Map<String, List<String>> fieldsMap = highlighting.get(solrDocument.get("id"));
List<String> highname = fieldsMap.get("name");
List<String> highdesc = fieldsMap.get("description");
System.out.println("highname======" + highname);
System.out.println("highdesc=====" + highdesc);
}
// (三) 将響應結果封裝到Bean
List<Product> products = queryResponse.getBeans(Product.class);
System.out.println(products + "+++++++++++");
for (Product product : products) {
System.out.println(product);
}
}
}
測試: SolrDaoTest
package liuxun.solrj.junit;
import static org.junit.Assert.*;
import java.io.IOException;
import org.apache.solr.client.solrj.SolrServerException;
import org.junit.Before;
import org.junit.Test;
import liuxun.solrj.bean.Product;
import liuxun.solrj.dao.SolrDao;
public class SolrDaoTest {
private SolrDao solrDao = new SolrDao();
@Test
public void testAddDefaultField() throws SolrServerException, IOException {
solrDao.addDefaultField();
}
@Test
public void testAddDynamicField() throws SolrServerException, IOException {
solrDao.addDynamicField();
}
@Test
public void testAddIndex() throws SolrServerException, IOException {
for(int i=1;i<=2;i++){
Product product=new Product();
product.setId(String.valueOf(i));
product.setName("蘋果(Apple)iPhone 5c 16G版 3G手機(白色)電信版");
product.setDesc("選擇“購機送費版”北京使用者享全新4G合約套餐資費全網最低!");
product.setPrice(9f);
solrDao.addIndex(product);
}
}
@Test
public void testUpdateIndex() throws IOException, SolrServerException {
Product product=new Product();
product.setId(String.valueOf(2));
product.setName("毛衣的毛衣黑色毛衣");
product.setDesc("女士專用 三點不漏..");
product.setPrice(9f);
solrDao.updateIndex(product);
}
@Test
public void testDelIndex() throws SolrServerException, IOException {
solrDao.delIndex("2");
}
@Test
public void testFindIndex() throws SolrServerException {
solrDao.findIndex();
}
}
控制台列印:
在solr圖形界面搜尋:
Solr安裝插件與資料庫表進行同步
修改solrconfig.xml,添加下面這段代碼:
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
然後再solrconfig.xml檔案統計的目錄下新增上面聲明的data-config.xml。内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/solr_test"
user="root"
password="root"/>
<document>
<entity name="id" query="select id,name,manu from solr" dataSource="JdbcDataSource"></entity>
</document>
</dataConfig>
因為需要連接配接資料庫是以需要連接配接資料庫的jar 包,以及操作索引庫的jar 包,在collection 下面建立lib 目錄将jar 包拷貝到lib 目錄下 ( solr-dataimporthandler-4.7.0, solr-dataimporthandler-extras-4.7.0以及連接配接 mysql 的jar 包) 配置的目錄如下
測試導入:
查詢是否導入成功