solrJ是什么?
solrJ是操作solr的java客户端
Solrj(集群)和spring集成
resource.properties
#集群版
SOLRClOUD.SERVER.URL =192.168.168.128:2181,192.168.168.128:2182,192.168.168.128:2183
在applicationContext-solr.xml添加:
我们都知道solr没有真正的修改,所谓的修改只是先删除后插入的操作(根据id来覆盖记录) 所以这里封装了三种操作:
插入或修改(saveOrUpdate)
删除(deleteByIds)
查询(search)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.quhappy.basesolr.facade.ISolrFacade;
import com.quhappy.tools.base.DateUtil;
import com.quhappy.tools.base.StringUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@Transactional
@Service
public class SolrFacadeImpl implements ISolrFacade{
@Autowired
private SolrServer solrServer;
private final String SUCCESS = "success";
private final String ERROR = "error";
/**
* 查询记录(多条件查询)
* @param coreName solr核名称
* @param fq 过滤条件,切记不能用and和or来连接,要用&&和||连接
* fq = "(skuName:一日游* || productName:*迪士尼*) && productId:[5 TO 12]";
* @param sortField 排序条件 map.put("productId", true); true代表升序(asc),false代表降序(desc)
* @param returnFileds 返回的字段 returnFileds = {"productId","productName"};
* @param pageNum 需要展示的页数
* @param pageSize 每页的记录大小
* @param isFacet 是否开启facet分组查询
* @param FacetField 需要分组的字段名称
* @return Map
* status:状态 success 或 error
* message:返回消息
* totle:总记录数
* pageNum:当前页数
* facetCounts: 分组字段的总记录数 Map key:FacetField(分组的字段名称) value:分组后的总记录数
* data:json数组(JSONArray)字符串
*/
public Map searchManyCondition(String coreName, String fq, Map sortField,
String[] returnFileds, int pageNum, int pageSize, boolean isFacet, String[] FacetField){
Map map = new HashMap();
map.put("status", ERROR);
try{
if(StringUtil.isAllNullOrEmpty(coreName)){
map.put("message", "coreName不能为空");
return map;
}
//设置默认的collection
((CloudSolrServer) solrServer).setDefaultCollection(coreName);
//创建查询对象
SolrQuery query = new SolrQuery();
//默认查询所有
query.setQuery("*:*");
if(!StringUtil.isAllNullOrEmpty(fq)){
//设置过滤条件
query.addFilterQuery(fq);
}
if(sortField != null && sortField.size() > 0){
//设置排序
//遍历map的key和value
for(String key : sortField.keySet()){
Boolean value = sortField.get(key);
query.setSort(key, value?SolrQuery.ORDER.asc:SolrQuery.ORDER.desc);
}
}
//设置返回的字段
if(returnFileds != null){
query.setFields(returnFileds);
}
//设置分页
query.setStart((pageNum - 1) * pageSize);
query.setRows(pageSize);
//设置facet
if(isFacet){
query.setFacet(true);//设置facet=on
query.addFacetField(FacetField);//设置需要facet的字段
query.setFacetLimit(-1);//限制facet返回的数量 。-1表示不限制
query.setFacetMinCount(1);//设置返回的数据中每个分组的数据最小值,比如设置为1,则统计数量最小为1,不然不显示
}
//执行查询
//根据查询条件查询索引库
QueryResponse queryResponse = solrServer.query(query);
if(isFacet){
Map facetMap = new HashMap();
//执行查询
List facets = queryResponse.getFacetFields();// 返回的facet列表
for (FacetField facet :facets) {
List counts = facet.getValues();
facetMap.put(facet.getName(), counts.size());
}
map.put("facetCounts", facetMap);
}
//data:json数组
JSONArray ja = new JSONArray();
//取查询结果
SolrDocumentList solrDocumentList = queryResponse.getResults();
for (SolrDocument solrDocument : solrDocumentList) {
JSONObject jo = new JSONObject();
Map> fieldValueMap = solrDocument.getFieldValuesMap();
for(String key : fieldValueMap.keySet()){
Collection value = fieldValueMap.get(key);
Object[] oa = value.toArray();
if(oa.length > 1){//如果是多个值
JSONArray ja1 = new JSONArray();
for(Object o : oa){
ja1.add(o);
}
jo.put(key, ja1.toString());
}else{
jo.put(key, oa[0]);
}
}
ja.add(jo);
}
map.put("data", ja.toString());
//计算查询结果总页数
long recordCount = solrDocumentList.getNumFound();
// long pageCount = recordCount / pageSize;
// if (recordCount % pageSize > 0) {
// pageCount++;
// }
map.put("status", SUCCESS);
map.put("message", "查询成功");
map.put("totle", recordCount);
map.put("pageNum", pageNum);
}catch (Exception e) {
e.printStackTrace();
map.put("message", "出现异常:"+e.getMessage());
}
return map;
}
/**
* 查询记录(单条件查询)
* @param coreName solr核名称
* @param q 查询条件 q = "productTitle:迪士尼*"
* @param sortField 排序条件 map.put("productId", true); true代表升序(asc),false代表降序(desc)
* @param returnFileds 返回的字段 returnFileds = {"productId","productName"};
* @param pageNum 需要展示的页数
* @param pageSize 每页的记录大小
* @param isFacet 是否开启facet分组查询
* @param FacetField 需要分组的字段名称
* @return Map
* status:状态 success 或 error
* message:返回消息
* totle:总记录数
* pageNum:当前页数
* facetCounts: 分组字段的总记录数 Map key:FacetField(分组的字段名称) value:分组后的总记录数
* data:json数组(JSONArray)字符串
*/
public Map search(String coreName, String q, Map sortField,
String[] returnFileds, int pageNum, int pageSize, boolean isFacet, String[] FacetField){
Map map = new HashMap();
map.put("status", ERROR);
try{
if(StringUtil.isAllNullOrEmpty(coreName)){
map.put("message", "coreName不能为空");
return map;
}
//设置默认的collection
((CloudSolrServer) solrServer).setDefaultCollection(coreName);
//创建查询对象
SolrQuery query = new SolrQuery();
if(!StringUtil.isAllNullOrEmpty(q)){
//设置查询条件
query.setQuery(q);
}else{
//默认查询所有
query.setQuery("*:*");
}
if(sortField != null && sortField.size() > 0){
//设置排序
//遍历map的key和value
for(String key : sortField.keySet()){
Boolean value = sortField.get(key);
query.setSort(key, value?SolrQuery.ORDER.asc:SolrQuery.ORDER.desc);
}
}
//设置返回的字段
if(returnFileds != null){
query.setFields(returnFileds);
}
//设置分页
query.setStart((pageNum - 1) * pageSize);
query.setRows(pageSize);
//设置facet
if(isFacet){
query.setFacet(isFacet);//设置facet=on
query.addFacetField(FacetField);//设置需要facet的字段
query.setFacetLimit(-1);//限制facet返回的数量 。-1表示不限制
query.setFacetMinCount(1);//设置返回的数据中每个分组的数据最小值,比如设置为1,则统计数量最小为1,不然不显示
}
//执行查询
//根据查询条件查询索引库
QueryResponse queryResponse = solrServer.query(query);
if(isFacet){
Map facetMap = new HashMap();
//执行查询
List facets = queryResponse.getFacetFields();// 返回的facet列表
for (FacetField facet :facets) {
List counts = facet.getValues();
facetMap.put(facet.getName(), counts.size());
}
map.put("facetCounts", facetMap);
}
//data:json数组
JSONArray ja = new JSONArray();
//取查询结果
SolrDocumentList solrDocumentList = queryResponse.getResults();
for (SolrDocument solrDocument : solrDocumentList) {
JSONObject jo = new JSONObject();
Map> fieldValueMap = solrDocument.getFieldValuesMap();
for(String key : fieldValueMap.keySet()){
Collection value = fieldValueMap.get(key);
Object[] oa = value.toArray();
if(oa.length > 1){//如果是多个值
JSONArray ja1 = new JSONArray();
for(Object o : oa){
ja1.add(o);
}
jo.put(key, ja1.toString());
}else{
jo.put(key, oa[0]);
}
}
ja.add(jo);
}
map.put("data", ja.toString());
//计算查询结果总页数
long recordCount = solrDocumentList.getNumFound();
// long pageCount = recordCount / pageSize;
// if (recordCount % pageSize > 0) {
// pageCount++;
// }
map.put("status", SUCCESS);
map.put("message", "查询成功");
map.put("totle", recordCount);
map.put("pageNum", pageNum);
}catch (Exception e) {
e.printStackTrace();
map.put("message", "出现异常:"+e.getMessage());
}
return map;
}
/**
* 批量插入或更新记录
* @param jsonDocumentList 插入或更新的json字符串List。必须传id
* 样例:
* {"id":"123", "productId":123, "productTitle":"香港经典景点门票", "skuName":["挪亚方舟门票","张保仔维港晚间游"]}
* @param coreName solr的核名称
* @return Map
* status:状态 success 或 error
* message:返回状态消息
*/
@SuppressWarnings("rawtypes")
public Map saveOrUpdateBatch(List jsonDocumentList, String coreName){
Map map = new HashMap();
try{
map.put("status", ERROR);
if(StringUtil.isAllNullOrEmpty(coreName)){
map.put("message", "coreName不能为空");
return map;
}
//设置默认的collection
((CloudSolrServer) solrServer).setDefaultCollection(coreName);
//创建一个文档对象
Collection documentList = new ArrayList();
for(String jsonDocument : jsonDocumentList){
JSONObject json = JSONObject.fromObject(jsonDocument.toString());
if(json.has("id") && !StringUtil.isAllNullOrEmpty(String.valueOf(json.get("id")))){
//创建一个文档对象
SolrInputDocument document = new SolrInputDocument();
// 遍历拿数据
Iterator it = json.keys();
while (it.hasNext()) {
String key = (String)it.next();
Object value = json.get(key);
if(!(value instanceof JSONArray)){
//向文档中添加域
document.addField(key, value);
}else{//数组类型
JSONArray ja = JSONArray.fromObject(json.get(key));
for(Object o : ja){//遍历数组的值
//向文档中添加域
document.addField(key, o);
}
}
}
documentList.add(document);
}else{
map.put("message", "id不能为空");
return map;
}
}
//把文档添加到索引库
solrServer.add(documentList);
//提交
solrServer.commit();
map.put("status", SUCCESS);
map.put("message", "提交成功");
}catch (Exception e) {
map.put("message", "出现异常:"+e.getMessage());
}
return map;
}
/**
* 插入或更新记录
* @param jsonDocument 插入或更新的json字符串。必须传id
* 样例:
* {"id":"123", "productId":123, "productTitle":"香港经典景点门票", "skuName":["挪亚方舟门票","张保仔维港晚间游"]}
* @param coreName solr的核名称
* @return Map
* status:状态 success 或 error
* message:返回状态消息
*/
@SuppressWarnings("rawtypes")
public Map saveOrUpdate(String jsonDocument, String coreName){
Map map = new HashMap();
try{
map.put("status", ERROR);
if(StringUtil.isAllNullOrEmpty(coreName)){
map.put("message", "coreName不能为空");
return map;
}
//设置默认的collection
((CloudSolrServer) solrServer).setDefaultCollection(coreName);
//创建一个文档对象
JSONObject json = JSONObject.fromObject(jsonDocument.toString());
if(json.has("id") && !StringUtil.isAllNullOrEmpty(String.valueOf(json.get("id")))){
//创建一个文档对象
SolrInputDocument document = new SolrInputDocument();
// 遍历拿数据
Iterator it = json.keys();
while (it.hasNext()) {
String key = (String)it.next();
Object value = json.get(key);
if(!(value instanceof JSONArray)){
//向文档中添加域
document.addField(key, value);
}else{//数组类型
JSONArray ja = JSONArray.fromObject(json.get(key));
for(Object o : ja){//遍历数组的值
//向文档中添加域
document.addField(key, o);
}
}
}
//把文档添加到索引库
solrServer.add(document);
//提交
solrServer.commit();
}else{
map.put("message", "id不能为空");
return map;
}
map.put("status", SUCCESS);
map.put("message", "提交成功");
}catch (Exception e) {
map.put("message", "出现异常:"+e.getMessage());
}
return map;
}
/**
* 删除记录根据id
* @param coreName solr的核名称
* @param ids 需要删除记录的id
* 样例:
* deleteByIds("collection1", "123")
* 或者
* String[] ids = {"123", "456"}; deleteByIds("collection1", ids)
* @return Map
* status:状态 success 或 error
* message:返回状态消息
*/
public Map deleteByIds(String coreName, String... ids){
Map map = new HashMap();
try{
map.put("status", ERROR);
if(StringUtil.isAllNullOrEmpty(coreName)){
map.put("message", "coreName不能为空");
return map;
}
//设置默认的collection
((CloudSolrServer) solrServer).setDefaultCollection(coreName);
for(String id : ids){
if(StringUtil.isAllNullOrEmpty(id)){
map.put("message", "id不能为空");
return map;
}
solrServer.deleteById(id);
//提交
solrServer.commit();
}
map.put("status", SUCCESS);
map.put("message", "删除成功");
}catch (Exception e) {
map.put("message", "出现异常:"+e.getMessage());
}
return map;
}
/**
* 保存日志记录
* @param type 日志类型, 比如:“订单”、“商品”、“账单” 等等
* @param content 日志内容
* @param recordNum 记录号,比如:订单编号、商品名称 等等
* @param recordSide 记录方,比如:分销商名称、供应商名称 等等
* @return Map
* status:状态 success 或 error
* message:返回状态消息
*/
public Map saveOrUpdateLog(String type, String content, String recordNum, String recordSide){
Map map = new HashMap();
try{
map.put("status", ERROR);
//设置默认的collection
((CloudSolrServer) solrServer).setDefaultCollection("log");
//创建一个文档对象
SolrInputDocument document = new SolrInputDocument();
document.addField("id", StringUtil.getOrderNum(""));
document.addField("type", type);
document.addField("content", content);
document.addField("recordNum", recordNum);
document.addField("recordSide", recordSide);
document.addField("createTime", DateUtil.dateTimeToString(new Date()));
//把文档添加到索引库
solrServer.add(document);
//提交
solrServer.commit();
map.put("status", SUCCESS);
map.put("message", "提交成功");
}catch (Exception e) {
map.put("message", "出现异常:"+e.getMessage());
}
return map;
}
}
下面是调用者示例,调用上面的通用方法
/**
* solr批量插入或更新记录
*/
@RequestMapping(value="/saveOrUpdateBatch")
public @ResponseBody void saveOrUpdateBatch(HttpServletRequest req) {
try {
List list = new ArrayList();
//第一条json记录
JSONObject jo = new JSONObject();
jo.put("id", "123");
jo.put("productId", 123);
jo.put("productTitle", "迪士尼");
JSONArray ja = new JSONArray();
ja.put("一日游");
ja.put("两日游");
jo.put("skuName", ja);
list.add(jo.toString());
//第二条json记录
JSONObject jo1 = new JSONObject();
jo1.put("id", "456");
jo1.put("productId", 456);
jo1.put("productTitle", "新加坡动物园");
JSONArray ja1 = new JSONArray();
ja1.put("动物园一日游");
ja1.put("动物园两日游");
jo1.put("skuName", ja1);
list.add(jo1.toString());
Map map = solrService.saveOrUpdateBatch(list, "collection1");
System.out.println(map.toString());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* solr插入或更新记录
*/
@RequestMapping(value="/saveOrUpdate")
public @ResponseBody void saveOrUpdate(HttpServletRequest req) {
try {
//第一条json记录
JSONObject jo = new JSONObject();
jo.put("id", "1234");
jo.put("productId", 1234);
jo.put("productTitle", "迪士尼1");
JSONArray ja = new JSONArray();
ja.put("一日游1");
ja.put("两日游1");
jo.put("skuName", ja);
Map map = solrService.saveOrUpdate(jo.toString(), "collection1");
System.out.println(map.toString());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* solr删除记录
*/
@RequestMapping(value="/deleteByIds")
public @ResponseBody void deleteByIds(HttpServletRequest req) {
try {
String[] ids = {"123", "456"};
Map map = solrService.deleteByIds("collection1", ids);
System.out.println(map.toString());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* solr查询记录
*/
@RequestMapping(value="/search")
public @ResponseBody void search(HttpServletRequest req) {
try {
Map sortField = new HashMap();
sortField.put("productId", true);
String fq = "orderStatus:2 && sendTime:["+timeBegin+" TO "+timeEnd+"]";
Map solrMap = iSolrFacade.searchManyCondition("collection1", fq, sortField, null, 1, 10, false, null);
System.out.println(map.toString());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
solrJ之增删改查的封装就讲到这里!