1. 程式人生 > >solr7.2.1使用——java封裝呼叫

solr7.2.1使用——java封裝呼叫

由於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>