在这篇文章中将通过代码带大家一步步实现spring和solrj的整合,并实现solrj的增删改查功能。
1.solrj的spring配置如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!--value为solr项目的部署地址,在配置文件里面已经配置好,通过spring加载-->
<bean id="catalogHttpSolrClient" class="org.apache.solr.client.solrj.impl.HttpSolrClient">
<constructor-arg index="0" value="${solrBaseUrl}catalog"/>
</bean>
</beans>
2.新建一个bean,属性名称要和solrcore的配置文件schema.xml的field一一对应,并用@field注解标识,否则实现不了solrj的增删改查。
package com.hover.bean;
import org.apache.solr.client.solrj.beans.Field;
public class CatalogBean {
@Field
private String catalogid;
@Field
private String catalogname;
@Field
private String fatherid;
@Field
private String photo;
@Field
private String iyear;
@Field
private String iway;
@Field
private String onsale;
public String getIyear() {
return iyear;
}
public void setIyear(String iyear) {
this.iyear = iyear;
}
public String getIway() {
return iway;
}
public void setIway(String iway) {
this.iway = iway;
}
public String getOnsale() {
return onsale;
}
public void setOnsale(String onsale) {
this.onsale = onsale;
}
public String getCatalogid() {
return catalogid;
}
public void setCatalogid(String catalogid) {
this.catalogid = catalogid;
}
public String getCatalogname() {
return catalogname;
}
public void setCatalogname(String catalogname) {
this.catalogname = catalogname;
}
public String getFatherid() {
return fatherid;
}
public void setFatherid(String fatherid) {
this.fatherid = fatherid;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
}
3.下面是service类
(1)向solr插入一条数据有两种方式:新建一个SolrInputDocument和直接添加我们新建的bean。
(2)删除操纵要慎用,否则数据不可恢复。
package com.hover.service;
import com.hover.bean.CatalogBean;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.FacetParams;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class CataLogService {
@Resource(name = "catalogHttpSolrClient")
private SolrClient client;
public void closeClient() throws Exception {
client.commit();
client.close();
}
public void addDoc(SolrInputDocument doc) throws Exception {
client.add(doc);
client.commit();
client.close();
}
public void addBean(CatalogBean bean) throws Exception {
client.addBean(bean);
client.commit();
client.close();
}
public void delete() throws Exception {
//1.删除一个
//updateResponse = client.deleteById("0");
//2.删除多个
// List<String> ids = new ArrayList<String>();
// ids.add("10");
// ids.add("11");
// updateResponse = client.deleteById(ids);
//3.根据查询条件删除数据,这里的条件只能有一个,不能以逗号相隔
//updateResponse = client.deleteByQuery("fatherid:0");
//
// //4.删除全部,删除不可恢复
client.deleteByQuery("*:*");
client.commit();
client.close();
}
/**
* 更新某一个属性的值
* @param id
* @param field
* @param value
* @throws Exception
*/
public void updateSet(int id, String field, String value) throws Exception {
SolrInputDocument doc = new SolrInputDocument();
HashMap<String, Object> operation = new HashMap<String, Object>();
operation.put("set", value);
doc.addField(field, operation);
doc.addField("catalogid", id);
client.add(doc);
}
/**
* 数值型属性累加操作
* @param id
* @param field
* @param value
* @throws Exception
*/
public void updateInc(int id, String field, int value) throws Exception {
SolrInputDocument doc = new SolrInputDocument();
HashMap<String, Object> operation = new HashMap<String, Object>();
operation.put("inc", value);
doc.addField(field, operation);
doc.addField("catalogid", id);
client.add(doc);
}
/**
* 多值属性附加一个值
* @param id
* @param field
* @param value
* @throws Exception
*/
public void updateAdd(int id, String field, String value) throws Exception {
SolrInputDocument doc = new SolrInputDocument();
HashMap<String, Object> operation = new HashMap<String, Object>();
operation.put("add", value);
doc.addField(field, operation);
doc.addField("catalogid", id);
client.add(doc);
}
/**
* field多值属性附加多个值
* @param id
* @param field
* @param list
* @throws Exception
*/
public void updateMultiValueAdd(int id, String field, List<String> list) throws Exception {
SolrInputDocument doc = new SolrInputDocument();
Map<String,List<String>> photos=new HashMap<String, List<String>>();
photos.put("add", list);
doc.addField(field, photos);
doc.addField("catalogid", id);
client.add(doc);
}
/**
* solr查询数据
* @return
* @throws Exception
*/
public QueryResponse query() throws Exception {
SolrQuery query = new SolrQuery();
//q 查询字符串,如果查询所有*:*
query.set("q", "catalogid:*");
//fq 过滤条件,过滤是基于查询结果中的过滤
//query.set("fq", "catalogname:*驰*");
//fq 此过滤条件可以同时搜索出奔驰和宝马两款车型,但是需要给catalogname配置相应的分词器
//query.set("fq", "catalogname:奔驰宝马");
//sort 排序,请注意,如果一个字段没有被索引,那么它是无法排序的
query.set("sort", "catalogid desc");
//start row 分页信息,与mysql的limit的两个参数一致效果
query.setStart(0);
query.setRows(100);
//fl 指定返回那些字段内容,用逗号或空格分隔多个
//query.set("fl", "catalogid,photo");
return client.query(query);
}
/**
* facet:solr多级分类功能
* facet是solr的一个重要特性,可以一次实现根据多个字段的分类统计
* @return
* @throws Exception
*/
public QueryResponse facet() throws Exception {
SolrQuery query = new SolrQuery();
query.set("q", "*:*");//必须有查询条件,否则一下操作都是没有意义的,会出现null的情况
//query.set("fq", "catalogname:*驰*");//过滤条件是建立在上述查询条件的基础之上的
query.setFacet(true);//设置facet=true,默认为true
//这里设置的开始index和行数是没有作用的
//query.setStart(0);
//query.setRows(10);
query.addFacetField(new String[] {"iyear", "iway", "onsale"});//设置需要facet的字段
query.setFacetLimit(5);//限制facet返回的数量
//query.setFacetSort("index");//默认是按count来排序的
query.setFacetSort(FacetParams.FACET_SORT_COUNT);
return client.query(query);
}
}
4.下面是test类
import com.hover.bean.CatalogBean;
import com.hover.service.CataLogService;
import org.apache.solr.client.solrj.response.FacetField;
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.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/*.xml")
public class TestCataLogService {
@Autowired
CataLogService cataLogService;
@Test
public void testAddDoc() throws Exception {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("catalogid", 28);
doc.addField("catalogname", "测试车型update");
doc.addField("fatherid", 0);
doc.addField("photo", "/img.jpg");
doc.addField("iyear", "2017");
doc.addField("iway", "ceshi");
doc.addField("onsale", "1");
cataLogService.addDoc(doc);
}
@Test
public void testAddBean() throws Exception {
CatalogBean bean = new CatalogBean();
bean.setCatalogid("29");
bean.setCatalogname("测试");
bean.setFatherid("1");
bean.setPhoto("/car.jpg");
bean.setOnsale("1");
bean.setIway("ceshi");
bean.setIyear("2017");
cataLogService.addBean(bean);
}
@Test
public void testDelete() throws Exception {
cataLogService.delete();
}
@Test
public void testUpdate() throws Exception {
cataLogService.updateSet(44, "catalogname", "测试");
cataLogService.updateInc(44, "fatherid", 1);
cataLogService.updateAdd(44, "photo", "/dasd.png");
List<String> list = new ArrayList<String>();
list.add("1.jpg");
list.add("2.jpg");
list.add("3.jpg");
list.add("4.jpg");
cataLogService.updateMultiValueAdd(44, "photo", list);
cataLogService.closeClient();
}
@Test
public void testQuery() throws Exception {
QueryResponse queryResponse = cataLogService.query();
SolrDocumentList results = queryResponse.getResults();
System.out.println(results.toString());
System.out.println("total:" + results.getNumFound());
for (SolrDocument solrDocument: results) {
System.out.println("-------" + solrDocument.get("catalogid") + "-------");
System.out.println("车型id:" + solrDocument.get("catalogid"));
System.out.println("车型名称:" + solrDocument.get("catalogname"));
System.out.println("车型fatherId:" + solrDocument.get("fatherid"));
System.out.println("车型照片:" + solrDocument.get("photo"));
System.out.println();
}
}
@Test
public void testFacet() throws Exception {
//调用service获取solrclient的查询结果
QueryResponse queryResponse = cataLogService.facet();
//获取查询的结果总数
System.out.println("------total:" + queryResponse.getResults().getNumFound());
//获取一级类List
List<FacetField> facetFieldList = queryResponse.getFacetFields();
for (FacetField facetField: facetFieldList) {
//输出一级类名称
System.out.println("facetFeildName:" + facetField.getName() + "---count:" + facetField.getValues().size());
List<FacetField.Count> countlist = facetField.getValues();
for (FacetField.Count count: countlist) {
//输出二级类名称和count值
System.out.println(count.getName() + ":" + count.getCount());
}
System.out.println();
}
}
}
源码下载地址为https://github.com/putTheoryIntoPractice/solrDemo.git