1. 程式人生 > >企業級搜尋應用伺服器Solr4.10.4部署開發詳解(3)- Solr使用-使用java客戶端solrj進行增刪改查開發

企業級搜尋應用伺服器Solr4.10.4部署開發詳解(3)- Solr使用-使用java客戶端solrj進行增刪改查開發

(一)使用java客戶端solrj進行增刪改查開發

        前兩章講的是如何搭建部署Solr環境和使用Solr建立資料集合進行儲存查詢,下面我們需要更進一步,直接使用客戶端API進行開發,直接操作資料集合,進行增刪改查。

1. 加入客戶端API的jar包

使用客戶端API的jar包有兩種方式,一種是maven依賴,另外一種是下載jar包新增到path環境中。這裡只說maven依賴,下載jar包我不說,但是我提供jar以及相關依賴包供你下載,點選jolrj依賴jar包(http://pan.baidu.com/s/1pJ209ZX),進行下載

<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>4.10.4</version>
</dependency>

增加這個maven依賴後,會自動下載下面10jar包

2. 編寫資料訪問介面層

包的依賴問題解決後,我們就可以直接在專案中使用solrj客戶端進行開發了,還記得上一章裡建立【schema.xml】裡的欄位嗎,這次咱們就建立的實體類欄位就應該對上,連大小寫,下劃線都不能有差別。


先寫模型類程式碼,這個裡面引入了一個Fieid類,在每個引數定義前註解,如果不註解,儲存時就會提示儲存異常,欄位對應不上,相當於做了類似序列化之類的工作。最複雜的應該是查詢部分,設定引數時,名稱需要看SolrQuery的API。

Items類

import org.apache.solr.client.solrj.beans.Field;

/**
 * @author shuang
 * 
 */
public class Items {
	/** 編號 */
	@Field
	private Integer id;
	/** 名稱 */
	@Field
	private String name;
	/** 價格 */
	@Field
	private double price;
	/** 圖片 */
	@Field
	private String display_picture;
	/** 時間 */
	@Field
	private Integer release_time;
	/** 狀態 */
	@Field
	private Integer release_state;
	/** 交易量 */
	@Field
	private Integer deals;
	/** 瀏覽量 */
	@Field
	private Integer hits;

	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("編號:").append(id);
		sb.append(", 名稱:").append(name);
		sb.append(", 價格:").append(price);
		sb.append(", 交易量:").append(deals);
		sb.append(", 瀏覽量:").append(hits);
		sb.append(", 時間:").append(release_time);
		return sb.toString();
	}

	/**
	 * 獲取id 的值
	 * 
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * 設定id 的值
	 * 
	 * @param id
	 *            the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * 獲取name 的值
	 * 
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * 設定name 的值
	 * 
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 獲取price 的值
	 * 
	 * @return the price
	 */
	public double getPrice() {
		return price;
	}

	/**
	 * 設定price 的值
	 * 
	 * @param price
	 *            the price to set
	 */
	public void setPrice(double price) {
		this.price = price;
	}

	/**
	 * 獲取deals 的值
	 * 
	 * @return the deals
	 */
	public Integer getDeals() {
		return deals;
	}

	/**
	 * 設定deals 的值
	 * 
	 * @param deals
	 *            the deals to set
	 */
	public void setDeals(Integer deals) {
		this.deals = deals;
	}

	/**
	 * 獲取hits 的值
	 * 
	 * @return the hits
	 */
	public Integer getHits() {
		return hits;
	}

	/**
	 * 設定hits 的值
	 * 
	 * @param hits
	 *            the hits to set
	 */
	public void setHits(Integer hits) {
		this.hits = hits;
	}

	/**
	 * 獲取display_picture 的值
	 * 
	 * @return the display_picture
	 */
	public String getDisplay_picture() {
		return display_picture;
	}

	/**
	 * 設定display_picture 的值
	 * 
	 * @param display_picture
	 *            the display_picture to set
	 */
	public void setDisplay_picture(String display_picture) {
		this.display_picture = display_picture;
	}

	/**
	 * 獲取release_time 的值
	 * 
	 * @return the release_time
	 */
	public Integer getRelease_time() {
		return release_time;
	}

	/**
	 * 設定release_time 的值
	 * 
	 * @param release_time
	 *            the release_time to set
	 */
	public void setRelease_time(Integer release_time) {
		this.release_time = release_time;
	}

	/**
	 * 獲取release_state 的值
	 * 
	 * @return the release_state
	 */
	public Integer getRelease_state() {
		return release_state;
	}

	/**
	 * 設定release_state 的值
	 * 
	 * @param release_state
	 *            the release_state to set
	 */
	public void setRelease_state(Integer release_state) {
		this.release_state = release_state;
	}

}


然後繼續編寫測試類,測試類的url中test/test,前面一個test是專案名稱,後面是資料集合名稱,在solr中建立的資料集合名稱與模型類名稱可以不同
/**
 * @author shuang
 *
 */
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
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.params.ModifiableSolrParams;

import com.bbmm.mbs.model.Items;
import com.bbmm.mbs.model.Services;

public class SolrTest {
	private final static String url = "http://localhost:8080/test/test";

	public static void main(String[] args) {
		 new SolrTest().add();
//		new SolrTest().delete();
//		 new SolrTest().update();
//		 new SolrTest().query();
	}

	/**
	 * 新增
	 */
	public void add() {
		try {
			HttpSolrServer server = getSolrServer();
			List<Items> list = new ArrayList<Items>();
			for(int i = 0 ; i < 5;i++){
				Items item = new Items();
				item.setId(i+1);
				item.setName("item_" + (i+1));
				item.setPrice(500 * i);
				item.setRelease_time((int) (System.currentTimeMillis() /1000));
				item.setDeals(10 +i);
				item.setHits(50 * i);
				list.add(item); 
			}
			server.addBeans(list);
			server.commit();
			System.out.println("新增完成");
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 刪除
	 */
	public void delete() {
		try {
			HttpSolrServer server = getSolrServer();
			server.deleteById("1");
			server.commit();
			System.out.println("刪除完成");
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 修改
	 * **/
	public void update() {
		try {
			HttpSolrServer server = getSolrServer();
			Items item = new Items();
			item.setId(2);
			item.setName("item_modify");
			item.setPrice(5009);
			item.setRelease_time((int) (System.currentTimeMillis() /1000));
			item.setDeals(109);
			item.setHits(509);
			server.addBean(item);
			server.commit();
			System.out.println("修改完成");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 查詢
	 */
	@SuppressWarnings("unchecked")
	public void query() {
		try {
			HttpSolrServer server = getSolrServer();
			ModifiableSolrParams params = new ModifiableSolrParams();
			params.set("q", "id:1"); // q表示查詢字串
                        params.set("start", 0); // start是開始記錄數 分頁用
                        params.set("rows", 3); // rows是返回記錄條數 分頁用
                        params.set("sort", "price desc");//sort是排序欄位 欄位名 排序型別
                        params.set("fl", "id,name,price,releaseTime,deals,hits"); //fl是 fieldlist縮寫,就是需要返回的欄位列表,用逗號和空格隔開
			QueryResponse response = server.query(params);
			SolrDocumentList results = response.getResults();
			if (!results.isEmpty()) {
				List<Services> list = toBeanList(results, Services.class);
				for (Services s : list) {
					System.out.println(s);
				}
			}
			System.out.println("引數查詢完成");
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Solr文件物件轉Java物件
	 * 
	 * @param <E>
	 * @param record
	 * @param clazz
	 * @return Object
	 */
	public static Object toBean(SolrDocument record, Class<Object> clazz) {
		Object o = null;
		try {
			o = clazz.newInstance();
		} catch (InstantiationException e) {
			System.out.println("Solr文件物件轉Java物件例項化異常:" + e.getMessage());
		} catch (IllegalAccessException e) {
			System.out.println("Solr文件物件轉Java物件非法訪問異常:" + e.getMessage());
		}
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			// log.warn("------------" + record.toString());
			Object value = record.get(field.getName());
			try {
				if (value != null) {
					BeanUtils.setProperty(o, field.getName(), value);
				}
			} catch (IllegalAccessException e) {
				System.out.println("Solr文件物件轉Java物件方法非法訪問異常:" + e.getMessage());
			} catch (InvocationTargetException e) {
				System.out.println("Solr文件物件轉Java物件呼叫目標異常:" + e.getMessage());
			}
		}
		return o;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List toBeanList(SolrDocumentList records, Class clazz) {
		List list = new ArrayList();
		for (SolrDocument record : records) {
			list.add(toBean(record, clazz));
		}
		return list;
	}
	private HttpSolrServer solrServer = null;

	// solrServer是執行緒安全的,所以在使用時需要使用單例的模式,減少資源的消耗
	public HttpSolrServer getSolrServer() {
		if (solrServer == null) {
			solrServer = new HttpSolrServer(url);
		}
		return solrServer;
	}
}


3. 測試資料增刪改查

在SolrTest.java類中依次開啟註釋執行add、delete、update、query來感受一下Solr的增刪改查功能,你就會發現她的魅力所在,當然,如果你要找到更大的成就感和快感,就需要更專心的學習Solr的API了


執行完成,在瀏覽器【http://localhost:8080/test/#/test/query】裡,query選項中,通過查詢,能看到剛才儲存進去的資料,如果你再執行delete方法,再查詢,就看不到編號為1的記錄了。如果修改,就會看到資料內容的變更,查詢就更要自己體會了。


總結:

到此,Solr單機的搭建部署、配置和java環境的開發已經全部完成。demo中的內容比較簡單,是為了儘快寫出文章與大家共勉,望大家諒解。其實Solr中還有很多更強大的功能待大家探索,比如聯合索引、模糊欄位匹配儲存、中文分詞等等。當然,這些功能,我會抽空寫出一些文章供大家參考,共同學習,我也是三天前才接觸Solr,所以寫出來記錄和加深自己印象,文中有不對的地方和建議,希望不吝賜教。