今天我的coding的模塊測試,因此閒暇之餘繼續研究solr,而後順帶寫了一個實例,隨便搞的,solr真心不熟,期待認識熱愛搜索的朋友,共同進步.
1.配置schema.xml文件[solr\collection1\conf\目錄下]html
由於schema默認定義了一些Field,咱們這裏選取[id,title,description, author]這幾個屬性,將id主鍵type配置爲string,其它幾個type配置爲自定義的ik分詞器java
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="title" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<field name="description" type="text_ik" indexed="true" stored="true"/>
<field name="author" type="text_ik" indexed="true" stored="true"/>
<field name="keywords" type="text_ik" indexed="true" stored="true"/>
Ik分詞器定義以下apache
<!--定義IK分詞類型-->
<fieldType name="text_ik" class="solr.TextField">
<!--索引時候的分詞器-->
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<!--查詢時候的分詞器-->
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
2. 編寫solr操做類SearchEngine.java,solrJ操做索引參看文章: http://www.cnblogs.com/dennisit/p/3623974.html
3.這裏演示solrj搜索高亮dom
/** * solrJ搜索 高亮顯示 * * @author pudongping * * @param server * solr客戶端 * @param queryString * 查詢串 * @param pageNum * 分頁 頁碼 * @param pageSize * 每頁顯示大小 * @return
*/
public static Page<QzoneArticle> queryComHighlight(SolrServer server, String queryString, int pageNum,int pageSize){ SolrQuery query = new SolrQuery(); query.setQuery(queryString); query.setHighlight(true);//開啓高亮功能
query.addHighlightField("description");//高亮字段
query.addHighlightField("keywords"); query.setHighlightSimplePre("<font color='red'>");//渲染標籤
query.setHighlightSimplePost("</font>");//渲染標籤
query.setStart((pageNum-1)*pageSize); query.setRows(pageSize); QueryResponse response = null; try { response = server.query(query); } catch (SolrServerException e) { e.printStackTrace(); return null; } //查詢結果集
SolrDocumentList lists = response.getResults(); //對象結果集
List<QzoneArticle> items = new ArrayList<QzoneArticle>(); //查詢到的記錄總數
long totalRow = Long.valueOf(response.getResults().getNumFound()).intValue(); String tmpId = ""; Map<String,Map<String,List<String>>> highlightMap=response.getHighlighting(); for (SolrDocument solrDocument : lists) { QzoneArticle at = new QzoneArticle(); tmpId=solrDocument.getFieldValue("id").toString(); at.setId(tmpId); at.setAuthor(solrDocument.getFieldValue("author").toString()); List<String> descList=highlightMap.get(tmpId).get("description"); List<String> keywsList=highlightMap.get(tmpId).get("keywords"); if(descList!=null && descList.size()>0){ at.setDescription(descList.get(0)); }else{ //獲取並設置高亮的字段title
at.setDescription(solrDocument.getFieldValue("description").toString()); } if(keywsList!=null && keywsList.size()>0){ at.setKeywords(keywsList.get(0)); }else{ at.setKeywords(solrDocument.getFieldValue("keywords").toString()); } items.add(at); } //填充page對象
return new Page<QzoneArticle>(pageNum, pageSize, totalRow, items); }
搜索高亮是找到關鍵字所在的記錄域,而後追加先後綴,從新填充到對象,這裏拆開來將是兩個步驟,第一步設置高亮域,第二步查詢結果追加渲染標記,填充到對象.因此這個能夠抽取出來寫成一個公用的方法
4.抽取高亮操做,實現公用方法post
/** * 根據關鍵字查詢 [測試經過 - 使用 solr內部轉換機制] * @param <T> * @param server solr客戶端 * @param keyword 搜索關鍵字 * @param pageNum 當前頁碼 * @param pageSize 每頁顯示的大小 * @param clzz 對象類型 * @return
*/
public static <T>Page<T> queryHighter(SolrServer server,String solrql, int pageNum,int pageSize,List<String> hlField, String preTag,String postTag,Class<T> clzz,String idName){ SolrQuery query = new SolrQuery(); query.setQuery(solrql); //設置高亮顯示
query.setHighlight(true); //添加高亮域
for(String hlf : hlField){ query.addHighlightField(hlf); } //渲染標籤
query.setHighlightSimplePre(preTag); query.setHighlightSimplePost(postTag); //分頁查詢
query.setStart((pageNum-1)*pageSize); query.setRows(pageSize); QueryResponse response = null; try { response = server.query(query); } catch (SolrServerException e) { e.printStackTrace(); return null; } //查詢到的記錄總數
long totalRow = Long.valueOf(response.getResults().getNumFound()).intValue(); //查詢結果集
List<T> items = new ArrayList<T>(); //查詢結果集
SolrDocumentList solrDocuments = response.getResults(); try { Object obj = null; Method m = null; Class<?> fieldType = null; Map<String,Map<String,List<String>>> highlightMap=response.getHighlighting(); for(SolrDocument solrDocument : solrDocuments) { obj = clzz.newInstance(); Collection<String> fieldNames = solrDocument.getFieldNames(); //獲得全部的屬性名
for (String fieldName : fieldNames) { //須要說明的是返回的結果集中的FieldNames()比類屬性多
Field[] filedArrays = clzz.getDeclaredFields(); //獲取類中全部屬性
for (Field f : filedArrays) { //若是實體屬性名和查詢返回集中的字段名一致,填充對應的set方法
if(f.getName().equals(fieldName)){ //獲取到的屬性名 //private java.lang.String com.test.model.Article.id
f = clzz.getDeclaredField(fieldName); //屬性類型 //private java.lang.String com.test.model.Article.id
fieldType = f.getType(); //構造set方法名 setId
String dynamicSetMethod = dynamicMethodName(f.getName(), "set"); //獲取方法 //public void com.test.model.Article.setId(java.lang.String)
m = clzz.getMethod(dynamicSetMethod, fieldType); //獲取到的值
LOG.info(f.getName() + "-->" + dynamicSetMethod+ "=" + fieldType.cast(solrDocument.getFieldValue(fieldName))); //獲取fieldType類型
fieldType = getFileType(fieldType); //獲取到的屬性
m.invoke(obj, fieldType.cast(solrDocument.getFieldValue(fieldName))); for(String hl : hlField){ if(hl.equals(fieldName)){ String idv = solrDocument.getFieldValue(idName).toString(); List<String> hlfList=highlightMap.get(idv).get(fieldName); if(null!=hlfList && hlfList.size()>0){ //高亮添加
m.invoke(obj, fieldType.cast(hlfList.get(0))); }else{ //正常添加
m.invoke(obj, fieldType.cast(solrDocument.getFieldValue(fieldName))); } } } } } } items.add(clzz.cast(obj)); } } catch (Exception e) { LOG.error("highlighter query error." + e.getMessage(), e); e.printStackTrace(); } //填充page對象
return new Page<T>(pageNum, pageSize, totalRow, items); } public static Class<?> getFileType(Class<?> fieldType){ // 若是是 int, float等基本類型,則須要轉型
if (fieldType.equals(Integer.TYPE)) { return Integer.class; } else if (fieldType.equals(Float.TYPE)) { return Float.class; } else if (fieldType.equals(Double.TYPE)) { return Double.class; } else if (fieldType.equals(Boolean.TYPE)) { return Boolean.class; } else if (fieldType.equals(Short.TYPE)) { return Short.class; } else if (fieldType.equals(Long.TYPE)) { return Long.class; } else if(fieldType.equals(String.class)){ return String.class; }else if(fieldType.equals(Collection.class)){ return Collection.class; } return null; }
須要說明的是,這裏的方法定義並非很完善,由於反射的屬性多是一個集合,因此在利用反射轉換以前,須要進行更精確地判斷,這實例中實體對象中的屬性爲簡單類型,因此這個方法能夠處理.
5.junit測試測試
package com.test.search; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.apache.solr.client.solrj.SolrServer; import org.junit.Before; import org.junit.Test; import com.plugin.page.Page; import com.plugin.solr.client.SolrClient; import com.plugin.solr.engine.SolrEngineHandler; import com.test.model.QzoneArticle; public class SolrTest { private SolrServer server; @Before public void init(){ String solrURL = "http://localhost:8888/solr"; server = SolrClient.getHttpSolrServer(solrURL); } @Test public void qzoneAdd(){ List<QzoneArticle> lists = new ArrayList<QzoneArticle>(); QzoneArticle qz1 = new QzoneArticle(); qz1.setId(UUID.randomUUID().toString()); qz1.setAuthor("蘇若年"); qz1.setDescription("Java程序猿, 愛音樂,愛生活,愛文字"); qz1.setKeywords("Java,音樂,生活,文字"); QzoneArticle qz2 = new QzoneArticle(); qz2.setId(UUID.randomUUID().toString()); qz2.setAuthor("林雲熙"); qz2.setDescription("文字控,我無悔,縱是情殤離人淚"); qz2.setKeywords("文字"); lists.add(qz1); lists.add(qz2); SearchEngine.addBeans(server, lists); } @Test public void qzoneDeLId(){ String id = "4f1b6b87-c824-4e38-a431-9a8f50e7af0c"; SolrEngineHandler.deleteById(server, "id", id); } @Test public void qzoneDeLIds(){ List<String> ids = new ArrayList<String>(); ids.add("d026e3ef-b89a-4ce2-9fbb-aa195ed2070b"); ids.add("9deb98ca-5a65-424d-95ad-91e87c2bde2c"); ids.add("5576650d-5517-43d5-987c-6d7135588e1f"); SolrEngineHandler.deleteByIds(server, "id", ids); } @Test public void qzoneDeLAll(){ SolrEngineHandler.deleteAllIndex(server); } @Test public void qzoneHLQuery(){ String solrql = "keywords:文字"; List<String> hlFields = new ArrayList<String>(); hlFields.add("description"); hlFields.add("keywords"); String preTag = "<font color='red'>"; String postTag = "</font>"; Page<QzoneArticle> page = SearchEngine.queryHighter(server,solrql , 1, 10, hlFields, preTag, postTag, QzoneArticle.class, "id"); formatPrint(page, solrql); } //測試經過
@Test public void qzoneCommonHLQuery(){ String solrql = "description:文字"; Page<QzoneArticle> page = SearchEngine.queryComHighlight(server, solrql , 1, 10); formatPrint(page, solrql); } @Test public void qzoneQuery(){ String solrql = "文字"; Page<QzoneArticle> page = SearchEngine.query(server,solrql , 1, 10,QzoneArticle.class); formatPrint(page, solrql); } @Test public void qzoneUpdate(){ QzoneArticle qz = new QzoneArticle(); qz.setId("5576650d-5517-43d5-987c-6d7135588e1f"); qz.setAuthor("林雲熙"); qz.setDescription("文字控,我無悔,縱是情殤離人淚"); qz.setKeywords("文字"); SearchEngine.updateBean(server, qz, "id"); } @Test public void pingSolr(){ System.out.println("ping solr result: " +SolrEngineHandler.ping(server)); } public void formatPrint(Page<QzoneArticle> page,String solrql){ System.out.println("查詢: " + solrql + "\t\t頁碼" + page.getPageNum() + "/" + page.getTotalPage() + ",總共找到" + page.getTotalRow()+"條符合的記錄.\n"); for(QzoneArticle qz: page.getItems()){ System.out.println("做者:" + qz.getAuthor()); System.out.println("描述:" + qz.getDescription()); System.out.println("關鍵字:" + qz.getKeywords() + "\n\n"); } } }
搜索結果集展現以下:ui
查詢: keywords:文字 頁碼1/1,總共找到2條符合的記錄. 做者:林雲熙 描述:<font color='red'>文字</font>控,我無悔,縱是情殤離人淚 關鍵字:<font color='red'>文字</font> 做者:蘇若年 描述:Java程序猿, 愛音樂,愛生活,愛<font color='red'>文字</font> 關鍵字:Java,音樂,生活,<font color='red'>文字</font>
轉載請註明出處:[http://www.cnblogs.com/dennisit/p/3623984.html]spa