solr7.2.1使用——java封裝呼叫
阿新 • • 發佈:2019-02-14
由於solr在使用時需要進行引數拼接等大量重複操作,所以對solr呼叫這塊進行了簡單封裝:
1、對應實體新增solr欄位註解(注意:註解欄位都要在solr的core中配置)
2、通過反射獲取註解欄位中非空值拼接搜尋引數、可以設定欄位精確匹配,預設非精確匹配
只需要傳入對應實體,和分頁引數即可、使用者不需要了解實現直接呼叫即可
先上使用例項:
實體註解:
@SolrField private String title; private String titleTranslation; @SolrField(isLike=false)//精確匹配 private String journalName;
方法呼叫:
@RequestMapping(value = "list") public String list(GxMagazine gxMagazine, Model model, HttpServletRequest request, HttpServletResponse response) { Map<String, ORDER> sort = new HashMap<String, ORDER>(); sort.put("createDate", ORDER.desc); Page<GxMagazine> page = new Page<>(request, response, pageSize); SolrDocumentList results = SolrUtil.searchProcudt(gxMagazine, sort, page, Global.getConfig("solr_core_magazine")); model.addAttribute("page", page);//分頁物件 model.addAttribute("list", results);//資料結果集 把solr裡的實體跟java的實體配成一樣 直接呼叫即可 return "front/res/magazineList"; }
ok頁面呼叫:
<c:forEach items="${list }" var="var" varStatus="status"> <span class="new-conDetail">${var.datasource }</span> </c:forEach>
solr封裝工具類:
package com.qhwl.common.solr; import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrQuery.ORDER; 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.SolrDocumentList; import com.qhwl.admin.gx.entity.res.GxMagazine; import com.qhwl.common.config.Global; import com.qhwl.common.persistence.Page; import com.qhwl.common.utils.StringUtils; public class SolrUtil { //指定solr伺服器的地址 private final static String SOLR_URL = Global.getConfig("solr_url"); /** * * @param obj 搜尋實體物件 * @param sortMap 排序 * @param page 分頁物件 * @param solr_core solr對應core * @return */ public static SolrDocumentList searchProcudt(Object obj, Map<String, ORDER> sortMap, Page page,String solr_core ) { // 建立連線 HttpSolrClient server = new HttpSolrClient.Builder(SOLR_URL + solr_core).withConnectionTimeout(10000).withSocketTimeout(60000).build(); // 查詢條件 SolrQuery query = new SolrQuery(); Field[] fields = obj.getClass().getDeclaredFields(); StringBuilder sbl = new StringBuilder(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; try { // 設定欄位可見否則無法獲取私有屬性 f.setAccessible(true); Object o = f.get(obj); // 只獲取非空欄位和配置solr註解欄位 SolrField sf = f.getAnnotation(SolrField.class); if (o != null && StringUtils.isNotBlank(o.toString()) && sf != null) { sbl.append(" AND ");// AND sbl.append(f.getName()); sbl.append(":"); if (sf.isLike()) { sbl.append("*" + parseKeywords(f.get(obj).toString()) + "*"); } else { sbl.append(parseKeywords(f.get(obj).toString())); } System.out.println("屬性名:" + f.getName() + " 屬性值:" + f.get(obj).toString()); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } if (sbl.length() > 0) { String s = sbl.toString(); s = s.substring(" AND ".length(), sbl.length()); query.setQuery(s);// 按條件查詢 } else { query.setQuery("*:*");// 無引數,就查全部 } // 排序 if (sortMap != null) for (String key : sortMap.keySet()) { ORDER value = sortMap.get(key); if (StringUtils.isNotBlank(key) && value!=null) { query.addSort(key, value); } } // 分頁 int start = (page.getPageNo() - 1) * page.getPageSize(); int size = page.getPageSize(); // 將初始偏移量指定到結果集中。可用於對結果進行分頁。預設值為 0 query.set("start", start); // 返回文件的最大數目。預設值為 10。 query.set("rows", size); // 指定文件結果中應返回的 Field 集,作為逗號分隔。預設為 “*”,指所有的欄位。“score” 指還應返回記分。 query.setParam("fl", "score,*"); // 執行查詢 QueryResponse response = null; try { response = server.query(query); } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } SolrDocumentList results = response.getResults(); long rowCount = results.getNumFound();// 搜尋到的總條數 int QTime = response.getQTime();// 耗時 int status = response.getStatus();// 狀態 System.out.println("QTime:"+QTime+"|status:"+status); page.setCount(rowCount);// 總條數 return results; } /** * solr 官方的處理方法 * 如果query中帶有非法字串,結果直接報錯,所以你對使用者的輸入必須要先做處理 * @param s * @return */ protected static String parseKeywords(String s) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); // These characters are part of the query syntax and must be escaped if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~' || c == '*' || c == '?' || c == '|' || c == '&' || c == ';' || c == '/' || Character.isWhitespace(c)) { sb.append('\\'); } sb.append(c); } return sb.toString(); } public static void main(String[] args) throws Exception { // Map<String, Object> param=new HashMap<String, Object>(); // param.put("id", "1"); GxMagazine gxMagazine =new GxMagazine(); gxMagazine.setTitle("title"); Map<String, ORDER> sort=new HashMap<String, ORDER>(); sort.put("id", ORDER.desc); SolrDocumentList results = searchProcudt(gxMagazine,sort,new Page<>(1, 10),Global.getConfig("solr_core_magazine")); System.out.println("name:"+results.get(0).get("title")); } }
自定義solr註解:
package com.qhwl.common.solr;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**由於solr並不需要配置所有資料所以反射獲取欄位是隻需要取註解欄位即可
* solr獲取欄位註解定義
* @author ztj
* 預設有此註解便視為solr配置欄位
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SolrField {
/**
* 是否模糊搜尋欄位
*/
boolean isLike() default true;
/**
* 反射型別
*/
Class<?> fieldType() default Class.class;
}
jar:
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>7.2.1</version>
</dependency>