Solr是apache的頂級開源項目,它是使用java開發 ,基於lucene的全文檢索服務器。php
Solr比lucene提供了更多的查詢語句,並且它可擴展、可配置,同時它對lucene的性能進行了優化。java
Solr是如何實現全文檢索的呢?mysql
索引流程:solr客戶端(瀏覽器、java程序)能夠向solr服務端發送POST請求,請求內容是包含Field等信息的一個xml文檔,經過該文檔,solr實現對索引的維護(增刪改)web
搜索流程:solr客戶端(瀏覽器、java程序)能夠向solr服務端發送GET請求,solr服務器返回一個xml文檔。sql
Solr一樣沒有視圖渲染的功能。數據庫
Lucene 是一個全文檢索引擎工具包,它是一個 jar 包,不能獨立運行,對外提供服務。apache
Solr 是一個全文檢索服務器,它能夠單獨運行在 servlet 容器,能夠單獨對外提供搜索和索引功能。Solr 比 lucene 在開發全文檢索功能時,更快捷、更方便。 json
solr 和 lucene 的版本時同步更新的,最新版本是5.2.1數組
下載地址:http://archive.apache.org/dist/lucene/solr/瀏覽器
jdk:1.7及以上 solr:4.10.3 mysql:5x web服務器:tomcat7
Solrhome是solr服務運行的主目錄,一個solrhome目錄裏面包含多個solrcore目錄,一個solrcore目錄裏面了一個solr實例運行時所須要的配置文件和數據文件。
每個solrcore均可以單獨對外提供搜索和索引服務。 多個solrcore之間沒有關係。
solrhome: solr-4.10.3\example\solr solrcore: solr-4.10.3\example\solr\collection1 包含配置文件,索引文件日誌信息
安裝 solrcore 須要先安裝 solrhome 將上面solrhome下的文件拷貝到web.xml中指定的solrhome中便可
配置 solrcore 的 conf 目錄下的 solrconfig.xml 配置文件,來配置 solrcore 的運行信息。
在該文件中,主要配置三個標籤:lib 標籤、datadir標籤、requestHandler 標籤。
solrcore 須要添加一個擴展依賴包,經過 lib 標籤來指定依賴包的地址
solr.install.dir 表示 solrcore 的安裝目錄
拷貝 example 目錄下的 contrib 和 dis 目錄到
修改 lib 標籤
每一個 solrcore 都有本身的索引文件目錄,默認在 solrcore 目錄下的 data 中。
data數據目錄下包括了index索引目錄 和tlog日誌文件目錄。 若是不想使用默認的目錄也能夠經過solrConfig.xml更改索引目錄 ,以下:
requestHandler 請求處理器,定義索引和搜索的訪問方式。 經過 /update 維護索引,能夠完成對索引的添加、修改、刪除操做。
提交 xml、json 數據完成索引維護。經過 /select 搜索索引
設置搜索參數完成搜索,搜索參數也能夠設置一些默認值,以下:<requestHandler name="/select" class="solr.SearchHandler">
<!-- 設置默認的參數值,能夠在請求地址中修改這些參數-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int><!--顯示數量-->
<str name="wt">json</str><!--顯示格式-->
<str name="df">text</str><!--默認搜索字段-->
</lst>
</requestHandler>
複製代碼
儀表盤,顯示 solr 實例運行時間、版本、系統資源、jvm等信息。 、
solr 運行日誌信息
Cloud即SolrCloud,即Solr雲(集羣),當使用Solr Cloud模式運行時會顯示此菜單.
solrcore 的管理界面,這裏能夠添加 solrcore 實例。
solr 在 jvm 運行環境中的屬性信息。
顯示 solr server 中當前活躍線程信息,同時也能夠跟蹤線程運行棧信息。
選擇一個 solrcore 進行詳細操做,以下:
經過此界面能夠測試索引分析器和搜索分析器的執行狀況。 注:solr 中,分析器是綁定在域類型中的。
能夠定義數據導入處理器,從關係數據庫導入到 solr 索引庫中。默認配置,須要手工配置。
經過 /update 表示更新索引,solr 默認根據 id(惟一約束) 域來更新 document 的內容,若是根據 id 值搜索不到 id 域則會執行添加操做,若是找到則更新。
經過此菜單能夠建立索引、更新索引、刪除索引等操做,界面以下:
經過/select執行搜索索引,必須指定「q」查詢條件方可搜索。
配置多solrcore的好處: 一、在進行 solrcloud 的時候,必須配置多solrcore 二、每一個 solrcore 之間是獨立的,均可以單獨對外提供服務。不一樣的業務模塊能夠使用不一樣的solrcore 來提供搜索和索引服務。
添加
在 schema.xml 文件中,主要配置了 solrcore 的一些數據信息,包括 Field 和 FieldType 的定義等信息,在 solr 中,Field 和 FieldType 都須要先定義後使用。
定義Field域
Name:指定域的名稱 Type:指定域的類型 Indexed:是否索引 Stored:是否存儲 Required:是否必須 multiValued:是否多值,好比商品信息中,一個商品有多張圖片,一個Field像存儲多個值的話,必須將multiValued設置爲true。
動態域
Name:指定動態域的命名規則
指定惟一鍵
id
其中的id是在Field標籤中已經定義好的域名,並且該域要設置爲required爲true。
一個schema.xml文件中必須有且僅有一個惟一鍵
複製域
Source:要複製的源域的域名 Dest:目標域的域名
由dest指的的目標域,必須設置multiValued爲true。
定義域的類型
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<!-- in this example, we will only use synonyms at query time <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/> -->
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
複製代碼
Name:指定域類型的名稱 Class:指定該域類型對應的solr的類型 Analyzer:指定分析器 Type:index、query,分別指定搜索和索引時的分析器 Tokenizer:指定分詞器 Filter:指定過濾器
使用ikanalyzer進行中文分詞
第一步:將ikanalyzer的jar包拷貝到如下目錄
第二步:將ikanalyzer的擴展詞庫的配置文件拷貝到 目錄
配置 FieldType
配置使用中文分詞的 field
重啓 tomcat
對京東案例中的 products 表的數據進行索引,因此須要定義對應的 field 域。
須要往索引庫添加的字段有: pid、name、catalog、catalog_name、price、description、picture
FieldType: 經分析,因爲中文分詞器已經配置完FieldType,因此目前FieldType已經知足須要,無需配置。
Field: Pid: 因爲pid在products表中是惟一鍵,並且在solr的shema.xml中已有一個id的惟一鍵配置,因此不須要再從新定義pid域。
Name:
<!-- 商品名稱 -->
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
複製代碼
Catalog、catalog_name:
<!-- 商品分類ID -->
<field name="product_catalog" type="string" indexed="true" stored="true"/>
<!-- 商品分類名稱 -->
<field name="product_catalog_name" type="string" indexed="true" stored="false"/>
複製代碼
Price:
<!-- 商品價格 -->
<field name="product_price" type="float" indexed="true" stored="true"/>
複製代碼
Description:
<!-- 商品描述 -->
<field name="product_description" type="text_ik" indexed="true" stored="false"/>
複製代碼
Picture:
<!-- 商品圖片地址 -->
<field name="product_picture" type="string" indexed="false" stored="true"/>
複製代碼
<!-- 目標域 -->
<field name="product_keywords" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<!-- 將商品名稱添加到目標域 -->
<copyField source="product_name" dest="product_keywords"/>
<!-- 將商品描述添加到目標域 -->
<copyField source="product_description" dest="product_keywords"/>
複製代碼
該插件能夠將數據庫中指定的sql語句的結果導入到solr索引庫中。
第一步:添加 jar 包 Dataimport的jar包(solr-4.10.3\dist\solr-dataimporthandler-extras-4.10.3.jar) 複製到
修改 solrconfig.xml 文件,添加 lib 標籤<lib dir="${solr.install.dir:../..}/contrib/dataimporthandler/lib" regex=".*\.jar" />
mysql 數據庫驅動包 複製 mysql 驅動包到:
修改solrconfig.xml文件,添加lib標籤<lib dir="${solr.install.dir:../..}/contrib/db/lib" regex=".*\.jar" />
第二步:配置 requesthandler 在 solrconfig.xml 中,添加一個 dataimport 的 requestHandler
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
複製代碼
- 第三步:建立 data-config.xml
在 solrconfig.xml 同級目錄下,建立 data-config.xml
![](http://pbzzkhjh1.bkt.clouddn.com/1c648865-30cb-4dbe-9133-525692211bf4.jpg)
```xml
<dataConfig>
<dataSource
type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/taotao"
user="root"
password="root"/>
<document>
<entity name="products" query="select pid,name,catalog,catalog_name,price,description,picture from products ">
<field column="pid" name="id" />
<field column="name" name="product_name" />
<field column="catalog" name="product_catalog" />
<field column="catalog_name" name="product_catalog_name" />
<field column="price" name="product_price" />
<field column="description" name="product_description" />
<field column="picture" name="product_picture" />
</entity>
</document>
</dataConfig>
複製代碼
solrj 就是 solr 服務器的 java 客戶端
jdk ide tomcat solrj
solrj 的依賴包和核心包
solrj 的擴展服務包
在solr中,索引庫中都會存在一個惟一鍵,若是一個Document的id存在,則執行修改操做,若是不存在,則執行添加操做。
@Test
public void insertAndUpdateIndex() throws Exception {
// 建立HttpSolrServer
HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr");
// 建立Document對象
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", "c001");
doc.addField("name", "solr test111");
// 將Document對象添加到索引庫
server.add(doc);
// 提交
server.commit();
}
複製代碼
@Test
public void deleteIndex() throws Exception {
// 建立HttpSolrServer
HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr");
// 根據指定的ID刪除索引
// server.deleteById("c001");
// 根據條件刪除
server.deleteByQuery("id:c001");
// 刪除所有(慎用)
server.deleteByQuery("*:*");
// 提交
server.commit();
}
複製代碼
@Test
public void search01() throws Exception {
// 建立HttpSolrServer
HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr");
// 建立SolrQuery對象
SolrQuery query = new SolrQuery();
// 輸入查詢條件
query.setQuery("product_name:小黃人");
// 執行查詢並返回結果
QueryResponse response = server.query(query);
// 獲取匹配的全部結果
SolrDocumentList list = response.getResults();
// 匹配結果總數
long count = list.getNumFound();
System.out.println("匹配結果總數:" + count);
for (SolrDocument doc : list) {
System.out.println(doc.get("id"));
System.out.println(doc.get("product_name"));
System.out.println(doc.get("product_catalog"));
System.out.println(doc.get("product_price"));
System.out.println(doc.get("product_picture"));
System.out.println("=====================");
}
}
複製代碼
solr的查詢語法
1.q - 查詢關鍵字,必須的,若是查詢全部使用*:*
。 請求的q是字符串
2.fq - (filter query)過慮查詢,做用:在q查詢符合結果中同時是fq查詢符合的,例如:: 請求fq是一個數組(多個值)
過濾查詢價格從1到20的記錄。 也能夠在「q」查詢條件中使用product_price:[1 TO 20],以下: 也能夠使用「*」表示無限,例如: 20以上:product_price:[20 TO ] 20如下:product_price:[ TO 20]3.sort - 排序,格式:sort=+<desc|asc>[,+<desc|asc>]… 。示例:
按價格降序4.start - 分頁顯示使用,開始記錄下標,從0開始
5.rows - 指定返回結果最多有多少條記錄,配合start來實現分頁。 實際開發時,知道當前頁碼和每頁顯示的個數最後求出開始下標。
6.fl - 指定返回那些字段內容,用逗號或空格分隔多個。
顯示商品圖片、商品名稱、商品價格7.df-指定一個搜索Field
也能夠在SolrCore目錄 中conf/solrconfig.xml文件中指定默認搜索Field,指定後就能夠直接在「q」查詢條件中輸入關鍵字。8.wt - (writer type)指定輸出格式,能夠有 xml, json, php, phps, 後面 solr 1.3增長的,要用通知咱們,由於默認沒有打開。
9.hl 是否高亮 ,設置高亮Field,設置格式前綴和後綴。
代碼
@Test
public void search02() throws Exception {
// 建立HttpSolrServer
HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr");
// 建立SolrQuery對象
SolrQuery query = new SolrQuery();
// 輸入查詢條件
query.setQuery("product_name:小黃人");
// query.set("q", "product_name:小黃人");
// 設置過濾條件
// 若是設置多個過濾條件的話,須要使用query.addFilterQuery(fq)
query.setFilterQueries("product_price:[1 TO 10]");
// 設置排序
query.setSort("product_price", ORDER.asc);
// 設置分頁信息(使用默認的)
query.setStart(0);
query.setRows(10);
// 設置顯示的Field的域集合
query.setFields("id,product_name,product_catalog,product_price,product_picture");
// 設置默認域
query.set("df", "product_keywords");
// 設置高亮信息
query.setHighlight(true);
query.addHighlightField("product_name");
query.setHighlightSimplePre("<em>");
query.setHighlightSimplePost("</em>");
// 執行查詢並返回結果
QueryResponse response = server.query(query);
// 獲取匹配的全部結果
SolrDocumentList list = response.getResults();
// 匹配結果總數
long count = list.getNumFound();
System.out.println("匹配結果總數:" + count);
// 獲取高亮顯示信息
Map<String, Map<String, List<String>>> highlighting = response
.getHighlighting();
for (SolrDocument doc : list) {
System.out.println(doc.get("id"));
List<String> list2 = highlighting.get(doc.get("id")).get(
"product_name");
if (list2 != null)
System.out.println("高亮顯示的商品名稱:" + list2.get(0));
else {
System.out.println(doc.get("product_name"));
}
System.out.println(doc.get("product_catalog"));
System.out.println(doc.get("product_price"));
System.out.println(doc.get("product_picture"));
System.out.println("=====================");
}
}
複製代碼