文章目錄
什麼是Solr
說到Solr ,不得不提起Lucene,Lucene是一個全文檢索引擎工具包,它只是一個jar包,不能獨立運行,對外提供服務。
而Solr是一個全文檢索服務器,它可以單獨運行在servlet容器,可以單獨對外提供搜索和索引功能。Solr比lucene在開發全文檢索功能時,更快捷、更方便。
Solr是apache的頂級開源項目,它是使用java開發 ,基於lucene的全文檢索服務器。
Solr的索引和搜索流程
索引流程:Solr客戶端(瀏覽器、java程序)可以向Solr服務端發送POST請求,請求內容是包含Field等信息的一個xml文檔,通過該文檔,Solr實現對索引的維護。
搜索流程:Solr客戶端(瀏覽器、java程序)可以向Solr服務端發送GET請求,Solr服務器返回一個xml/json文檔。
Solr界面
Dashboard
儀表盤,顯示了該Solr實例開始啓動運行的時間、相關Solr版本和Lucene、系統資源、JVM等信息。
Logging
顯示Solr運行出現的異常或警告
像這樣,十分尷尬
Core Admin
Solr Core的管理界面。在這裏可以添加SolrCore實例。
主要功能有Add Core(添加核心), Unload(卸載核心),Rename(重命名核心),Reload(重新加載核心),Optimize(優化索引庫) 。
關於Add Core的配置項說明
- name:給core起的名字;
- instanceDir:與我們在配置solr到tomcat裏時的solrhome裏新建的core文件夾名一致;
- dataDir:確認Add Core時,會在new_core目錄下生成名爲data的文件夾;
- config:new_core下的conf下的config配置文件(solrconfig.xml) ;
- schema: new_core下的conf下的schema文件(schema.xml) ;
Java Properties
Solr在JVM 運行環境中的屬性信息,包括類路徑、文件編碼、jvm內存設置等信息。
Tread Dump
顯示Solr Server中當前活躍線程信息,同時也可以跟蹤線程運行棧信息。
Core Selector
需要在Core Admin裏添加了Solr Core後纔有可選項,可以選擇一個Solr Core進行詳細操作,有關Core Selector裏的Solr Core裏的相關子面板功能,已經在下面做說明。
Solr Core的子面板功能
Analysis
通過此界面可以測試索引分詞器和搜索分詞器的執行情況。
dataimport
可以定義數據導入處理器,從關係數據庫將數據導入到Solr索引庫中,默認沒有配置,需要手工配置。假如沒有配置,dataimport面板沒有任何的功能顯示。
Document
通過對文檔的操作進行創建索引、更新索引、刪除索引等操作。
Query
通過/select執行搜索索引,指定查詢條件方可搜索。
schema.xml配置文件詳解
該配置文件在solrhome目錄下的相應solrcore 的conf目錄下
schema.xml主要配置SolrCore的相關信息,包括:Field和FieldType的定義等信息,在Solr中,Field和FieldType都需要先定義後使用。
其中Field配置如下:
- name:指定域的名稱(自定義)
- type:指定域的類型
- indexed:是否索引
是:(將分好的詞進行索引,索引的目的,就是爲了搜索)
否:不索引,也就是不對該field域進行搜索。
- stored:是否存儲
是:將field域中的內容存儲到文檔域中。存儲的目的,就是爲了搜索顯示用的
否:不將field域中的內容存儲到文檔域中。不存儲,則搜索中沒法獲取該field域的值。
-
required:是否必須
-
multiValued:是否多值,比如一個Field存儲多個值信息,必須將multiValued設置爲true。
關於Field中的配置項,也可參考自:lucene/solr 中Field類(域)的常用類型,以及Field屬性解析
其中dynamicField(動態域)配置如下:
舉個栗子,比如name爲“ *_i ”,那麼在使用這個字段的時候,任何以i結果的字段都被認爲符合這個定義。
其中uniqueKey的配置如下:
id是在Field標籤中已經定義好的域名,而且該域設置爲required爲true。
一個schema.xml文件中必須有且僅有一個唯一鍵
其中copyField(複製域)的配置如下:
copyField的應用場景: 其實說的簡單一點,比如現在你要查詢包涵"solr"的博客, 那麼你肯定要查內容,標題是否包含Java,但是solr不能像SQL那樣,where tittle like ‘%solr%’ or content like ‘%solr%’. 這個時候copyField就派上用場了, 定義一個新字段,將title和content 複製到這個新字段,索引的時候,直接從這個新字段查詢,這樣就達到目地了。
Source: 是Field域的名稱。
Dest:是destination的縮寫,目標域。
其中fieldType的配置如下:
常用的fieldType屬性
其中分詞器的配置項如下:
Name:指定域類型的名稱
Class:指定該域類型對應的solr的類型
Analyzer:指定分析器
- Type:index、query,分別指定搜索和索引時的分析器
Tokenizer:指定分詞器
Filter:指定過濾器
需要注意的是,Solr7以上才內置了中文分詞器,實現語義分詞,Solr7以下均不支持中文按語義分詞,需要手動配置中文分詞器,一般使用較多的爲IKAnalyzer分詞器,具體配置可戳:Apache Solr 4.9上配置IKAnalyzer中文分詞插件
實現MySQL數據庫數據導入到solr索引庫
配置solrconfig.xml
我們可以在這配置文件中配置數據導入處理器,從而實現dataimport的功能:從關係數據庫將數據導入到Solr索引庫中。首先查詢是否存在dataimport的requestHandler,如果不存在,因此需要手動添加。在solrconfig.xml中添加如下內容
<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
我們還需要創建一個data-config.xml文件,用來存放數據庫連接相關信息、SQL以及查詢結果映射對應域中的相關信息。在solrconfig.xml的同級目錄下,創建data-config.xml文件,添加內容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/new_schema?serverTimezone=UTC&tinyInt1isBit=false"
user="root"
password="root"/>
<document>
<entity name="products" query="select pid,pname,catalog_name,price,description,picture from products ">
<field column="pid" name="id"/>
<field column="pname" name="prod_pname"/>
<field column="catalog_name" name="prod_catalog_name"/>
<field column="price" name="prod_price"/>
<field column="description" name="prod_description"/>
<field column="picture" name="prod_picture"/>
</entity>
</document>
</dataConfig>
配置Field域名
修改與solrconfig.xml同目錄下的schema.xml,添加如下內容:
<field name="prod_pname" type="text_ik" indexed="true" stored="true" required="true" />
<field name="prod_catalog_name" type="string" indexed="true" stored="true" required="true" />
<field name="prod_price" type="tdouble" indexed="true" stored="true" required="true" />
<field name="prod_description" type="text_ik" indexed="true" stored="true" required="true" />
<field name="prod_picture" type="string" indexed="false" stored="true" required="true" />
導入相應jar包
配置完成之後,我們需要將solr目錄下的solr-dataimporthandler-4.9.0.jar、solr-dataimporthandler-extras-4.9.0.jar和mysql連接驅動jar包mysql-connector-java-8.0.11.jar加入到E:\tomcat7\tomcat-7\webapps\solr\WEB-INF\lib中
重啓Tomcat
重新啓動Tomcat,再打開Solr Core下的dataimport子面板,會顯示如下頁面,證明我們的dataimport功能部署完成
勾選上Clean、Commit選項,點擊Execute開始把products表中的數據導入到Solr中,等待一段時間,導入完成
此時Solr中存在我們products表中的數據
客戶端查詢語法
q:
指定域名進行關鍵字查詢,也可查詢所有文檔記錄,查詢多個條件可以條件之間用 AND 或 OR 關聯
#指定域名進行關鍵字查詢
prod_pname:花兒
#查詢所有
*:*
#多個條件查詢
prod_pname:花兒 AND prod_catalog_name:幽默雜貨
fq:
請求fq是一個數組(多個值),可以動態添加查詢條件
sort:
表示搜索出來的文檔按哪個域名進行升序或降序排序,格式爲sort=+<desc|asc>[,+<desc|asc>]….
prod_price:desc
start和rows:
start - 分頁顯示使用,開始記錄下標,從0開始
rows - 指定返回結果最多有多少條記錄,配合start來實現分頁
f1
指定返回哪些字段內容,用逗號或空格分隔多個(回顯)
df
指定一個搜索默認Field
wt
指定文檔輸出格式,可選,默認是json
hl
設置高亮,hl.fl 指定高亮域的名稱,一般對哪個域進行搜索就對哪個域做高亮
solrj的增刪改查
Solrj就是solr服務器的java客戶端
創建maven工程
要用solrj實現對solr索引庫的增刪改查操作,首先創建個maven工程,並在pom.xml添加以下依賴
<dependencies>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.9.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
solrj添加數據
@Test
public void addDoc() throws SolrServerException, IOException {
//1.創建連接對象
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//2.創建一個文檔對象
SolrInputDocument inputDocument = new SolrInputDocument();
//向文檔中添加域以及對應的值,注意:所有的域必須在schema.xml中定義過
inputDocument.addField("id", "1000");
inputDocument.addField("prod_pname", "sansung爆炸牌手機");
inputDocument.addField("prod_price", 666);
inputDocument.addField("prod_picture", "www.boom.png");
inputDocument.addField("prod_description", "喵喵喵喵喵手機");
inputDocument.addField("prod_catalog_name", "手機");
//3.將文檔寫入索引庫中
solrServer.add(inputDocument);
//提交
solrServer.commit();
System.out.println("添加成功");
}
solrj更新數據
@Test
public void updateDoc() throws SolrServerException, IOException {
//1.創建連接對象
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//2.創建一個文檔對象
SolrInputDocument inputDocument = new SolrInputDocument();
inputDocument.addField("id", "1");
inputDocument.addField("prod_pname", "蜘蛛俠手辦");
inputDocument.addField("prod_price", 999);
inputDocument.addField("prod_picture", "www.zhizhuxia.png");
inputDocument.addField("prod_description", "能力越大,責任越大");
inputDocument.addField("prod_catalog_name", "手辦");
//3.將文檔寫入索引庫中
solrServer.add(inputDocument);
//提交
solrServer.commit();
System.out.println("更新成功");
}
solrj刪除數據
@Test
public void deleteDoc() throws SolrServerException, IOException
{
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//刪除文檔
solrServer.deleteById("1000");
//提交
solrServer.commit();
System.out.println("刪除成功");
}
solrj查詢數據
@Test
public void testSimpleQ() throws Exception{
//1.創建連接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//2.創建查詢語句
SolrQuery query = new SolrQuery();
//3.設置查詢條件
query.set("q", "id:1");
//4.執行查詢
QueryResponse queryResponse = solrServer.query(query);
//5.取文檔列表public class SolrDocumentList extends ArrayList<SolrDocument>
SolrDocumentList documentList = queryResponse.getResults();
for (SolrDocument solrDocument : documentList) {
//取各個文檔信息
System.out.println("商品id:"+solrDocument.get("id")+" ");
System.out.println("商品標題:"+solrDocument.get("prod_pname")+" ");
System.out.println("商品價格:"+solrDocument.get("prod_price")+" ");
}
System.out.println("查詢成功");
}
這裏只是對solrj的增刪改查功能做了簡單操作,也可以戳:使用solrJ操作solr常用方法