solr環境的搭建請參考:http://www.cnblogs.com/xiao-zhang-blogs/p/7327814.html
- 1. Solr不支持搜索中文,辦法總會有的,添加中文分詞器。中文分詞器有:IKAnalyzer,mmseg4j等
a) 中文分詞指的是將一個漢字序列切分成一個一個單獨的詞。分詞就是將連續的字序列按照一定的規范重新組合成詞序列的過程。
b) 寫個程序看一下效果。(IKAnalyzer)
代碼:
package demo; import java.io.IOException; import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.wltea.analyzer.core.IKSegmenter; import org.wltea.analyzer.core.Lexeme; public class Test { public static void main(String[] args) throws IOException { String text = "我愛你中國,厲害了,我的國。我愛你!"; int topWordsCount=4; Map<String,Integer> wordsFrenMaps=getTextDef(text); sortSegmentResult(wordsFrenMaps,topWordsCount); } public static Map getTextDef(String text) throws IOException { Map<String, Integer> wordsFren=new HashMap<String, Integer>(); IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(text), true); Lexeme lexeme; while ((lexeme = ikSegmenter.next()) != null) { if(lexeme.getLexemeText().length()>1){ if(wordsFren.containsKey(lexeme.getLexemeText())){ wordsFren.put(lexeme.getLexemeText(),wordsFren.get(lexeme.getLexemeText())+1); }else { wordsFren.put(lexeme.getLexemeText(),1); } } } return wordsFren; } public static void sortSegmentResult(Map<String,Integer> wordsFrenMaps,int topWordsCount){ Iterator<Map.Entry<String,Integer>> wordsFrenMapsIterator=wordsFrenMaps.entrySet().iterator(); while (wordsFrenMapsIterator.hasNext()){ Map.Entry<String,Integer> wordsFrenEntry=wordsFrenMapsIterator.next(); System.out.println(wordsFrenEntry.getKey()+" 的次數為"+wordsFrenEntry.getValue()); } } }
效果:
在步驟1.2中教大家如何將中文分詞器添加到solr中。
- 2. 創建core數據來源一共有三種情況,分別是:1、通過java直接寫入。2、直接配置數據源。
a) 在E:\solrhome目錄下創建一個文件夾helloworld,將solr-6.6.0\example\example-DIH\solr\db文件夾下的conf文件夾賦值到helloworld文件夾下,如下圖:
b) 在solr的管理界面點擊Core Admin,點擊Add Core,輸入name值為helloworld,instanceDir值為helloworld,其他項不用改。注意:填寫的值必須為我們創建的文件夾的名稱,否則報錯。最后Add Core。
成功后:
c) 接下來,我們就在創建好的core中去寫入數據。
i. 第一種,直接通過java程序寫入。
代碼如下:
package test; import java.io.IOException; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; 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 org.apache.solr.common.util.NamedList; public class TestSolr { //solr的服務器地址 private final static String SOLR_URL = "http://localhost:8080/solr/"; /** * 往索引庫添加文檔 * @throws IOException * @throws SolrServerException */ public void addDoc() throws SolrServerException, IOException{ //獲得一個solr服務端的請求,去提交 ,選擇具體的某一個solr core //solr的服務器地址 //private final static String SOLR_URL = "http://localhost:8080/solr/"; HttpSolrClient solr = new HttpSolrClient(SOLR_URL + "helloworld"); try { //構造一篇文檔 SolrInputDocument document = new SolrInputDocument(); //往doc中添加字段,在客戶端這邊添加的字段必須在服務端中有過定義 document.addField("id", "1"); document.addField("name", "你好"); document.addField("description", "前進的中國你好"); solr.add(document); solr.commit(); } finally{ solr.close(); } } /** * 根據id從索引庫刪除文檔 */ public void deleteDocumentById() throws Exception { //選擇具體的某一個solr core HttpSolrClient server = new HttpSolrClient(SOLR_URL+"helloworld"); //刪除文檔 // server.deleteById("3"); //刪除所有的索引 server.deleteByQuery("*:*"); //提交修改 server.commit(); server.close(); } /** * 查詢 * @throws Exception */ public void querySolr() throws Exception{ HttpSolrClient solrServer = new HttpSolrClient(SOLR_URL+"helloworld"); SolrQuery query = new SolrQuery(); // String temp = "name:文 OR description:你"; // query.setQuery(temp); //下面設置solr查詢參數 //query.set("q", "*:*");// 參數q 查詢所有 query.set("q","好");//相關查詢,比如某條數據某個字段含有某個字 將會查詢出來 ,這個作用適用於聯想查詢 //參數fq, 給query增加過濾查詢條件 query.addFilterQuery("id:[0 TO 9]");//id為0-9 //參數df,給query設置默認搜索域 query.set("df", "name"); //參數sort,設置返回結果的排序規則 query.setSort("id",SolrQuery.ORDER.desc); //設置分頁參數 query.setStart(0); query.setRows(10);//每一頁多少值 //參數hl,設置高亮 query.setHighlight(true); //設置高亮的字段 query.addHighlightField("name"); //設置高亮的樣式 query.setHighlightSimplePre("<font color='red'>"); query.setHighlightSimplePost("</font>"); //獲取查詢結果 QueryResponse response = solrServer.query(query); //兩種結果獲取:得到文檔集合或者實體對象 //查詢得到文檔的集合 SolrDocumentList solrDocumentList = response.getResults(); //NamedList,一個有序的name/value容器,NamedList不像Map NamedList list = (NamedList) response.getResponse().get("highlighting"); System.out.println(list); System.out.println("查詢的結果"); System.out.println("總數量:" + solrDocumentList.getNumFound()); //遍歷列表 for (SolrDocument doc : solrDocumentList) { System.out.println("id:"+doc.get("id")+" name:"+doc.get("name")+" description:"+doc.get("description")); } } }
效果如下:
ii. 直接配置數據源(結構化數據存儲)
- 如何將中文分詞器加入到solr中
先下載mmseg4j的jar包,一共有三個,分別是:mmseg4j-analysis-1.9.1.jar、mmseg4j-core-1.10.0.jar和mmseg4j-solr-2.4.0.jar。
將mmseg4j-core-1.10.0.jar和mmseg4j-solr-2.4.0.jar放在apache-tomcat-8.0.32\webapps\solr\WEB-INF\lib目錄下。
(注意:不要將包mmseg4j-analysis-1.9.1.jar放到改目錄下,否則會報:java.lang.NoSuchMethodError: com.chenlb.mmseg4j.analysis.MMSegTokenizer.<init>(Lcom/chenlb/mmseg4j/Seg;)V錯誤信息,原因是:mmseg4j-solr已經包含了mmseg4j-analysis)
- 在core去配置。
沒有加入中文分詞器的效果,無論你選擇哪種類型,得到的結果如下:
添加中文分詞器:
首先mmseg4j有三種分詞方式:
<!-- mmseg4j的三種分詞方式--> <fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/dic"/> </analyzer> </fieldtype> <fieldtype name="textMaxWord" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" /> </analyzer> </fieldtype> <fieldtype name="textSimple" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="G:\ymy\solr\solr-5.4.1\server\solr\good\dic" /> </analyzer> </fieldtype>
把這些添加到E:\solrhome\helloworld\conf的managed-schema文件的325行左右。
這個文件里面的field 標簽里name存放的就是你所要分詞的名稱,type 放的是分詞的類型。這里我把name=”title” 的type改為textComplex。(在148行)
重啟tomcat,看一下效果(成功):
然后配置oracle數據源,這里我選用的表為books表
在managed-schema去添加字段類型和名稱(author和name配置文件中有,修改一下type即可,id配置文件中也有,127行)
<field name="name" type="string" indexed="true" stored="true"/> <field name="author" type="string" indexed="true" stored="true"/> <field name="summary" type="string" indexed="true" stored="true"/> <field name="count" type="int" indexed="true" stored="true"/>
配置數據庫映射:
首先,在E:\solrhome\helloworld\conf創建一個data-config.xml文件
文件內容:
<?xml version="1.0" encoding="UTF-8"?> <dataConfig> <dataSource name="source" type="JdbcDataSource" driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orcl" user="scott" password="tiger"/> <document name="mydemo"> <entity name="mydemo" pk="id" dataSource="source" query="select * from books" transformer="ClobTransformer"> <field column="id" name="id" /> <field column="name" name="name" /> <field column="author" name="author"/> <field column="summary" name="summary" /> <field column="count" name="count"/> </entity> </document> </dataConfig>
接着在E:\solrhome\helloworld\conf的solrconfig.xml配置文件中的<requestHandler name="/select" class="solr.SearchHandler">(743行)上面添加
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
將數據從數據庫導入到helloworld的core中,如下圖:
接着,查詢全部:
數據成功導入。