/**
* solr客户端操作基类,可以使用两种方式进行操作索引,第一种用普通javaBean,第二种使用有固定的solr注解字段javaBean
* javaBean操作的字段必须在solr服务器定义,否则会报错
*
*/
public class SolrBase {
private static String solrURL = "http://localhost:8983/solr";
private static Logger log = Logger.getLogger(SolrBase.class);
static {
solrURL = SystemConfig.getDefaultConfig("solr.server.url");
}
private static HttpSolrServer solrServer = null;
/**
* 单个索引添加或更新,修改时是按照Id进行覆盖的
* @param indexMap
*/
public void addIndex(Map indexMap){
if(indexMap ==null && indexMap.size()==0){
log.error("索引参数为空,请检查");
return;
}
try {
/**1、创建solrServer(HttpSolrServer和EmbeddedSolrServer)
* 其中HttpSolrServer必须依赖tomcat等WEB容器,EmbeddedSolrServer则不需要,但是需要
* 引入其它jar包,具体可以参照doc下得solr wiki.html
* **/
HttpSolrServer server = getSolrServer();
//server.deleteByQuery("*:*");//先删除默认数据,防止对理解产生混淆
/**2、solr要求doc的Field中必须存在一个Field为id,并且值为java.lang.String类型
* 并且要保证Id的唯一,否则最后添加的相同Id的域会覆盖前面的域,也就等于是更新
* **/
String id = UUID.randomUUID().toString();
SolrInputDocument doc = new SolrInputDocument();
if(indexMap.get("id") !=null){
id = (String)indexMap.get("id");
}
doc.addField("id",id);
/**3、对于需要使用doc添加的Field,必须先在schema.xml中进行配置,然后才可以使用,
* 关于schema的配置说明,可以参照lucene-solr.txt中得说明
* **/
Iterator iter = indexMap.keySet().iterator();
for(;iter.hasNext();){
String key = iter.next();
doc.addField(key, indexMap.get(key));
}
server.add(doc);
server.commit();//提交,将所有更新提交到索引中
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//solrServer是线程安全的,所以在使用时需要使用单例的模式,减少资源的消耗
public static HttpSolrServer getSolrServer(){
if(solrServer==null){
solrServer = new HttpSolrServer(solrURL);
}
return solrServer;
}
/**多个索引添加,对象字段必须用solr注解
* 使用POJO添加document
*/
public static void addIndexByList(List> objList){
try {
HttpSolrServer server = getSolrServer();
server.addBeans(objList);
server.commit();
log.info("提交成功");
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**添加或修改记录,按通用字段
* 修改时是按照Id进行覆盖的
* **/
public static void addIndexByCommBean(Message msg){
try {
HttpSolrServer server = getSolrServer();
if(StringUtils.isEmpty(msg.getId())){
msg.setId(UUID.randomUUID().toString());
}
server.addBean(msg);
server.commit();
} catch (IOException e) {
e.printStackTrace();
} catch (SolrServerException e) {
e.printStackTrace();
}
}
/**
* 查询
*/
public static void query(String q){
try {
HttpSolrServer server = getSolrServer();
//String q = "text:中";//q表示查询的内容
SolrQuery query = new SolrQuery(q);
/*query.setStart(0)
.setRows(3);//进行分页查询
query.setHighlight(true).setHighlightSimplePre("")
.setHighlightSimplePost("");//高亮
//只有将内容存储后才能进行展示,比如title_content查询结果就为空
query.setParam("hl.fl", "title,content");*/
QueryResponse resp = server.query(query);
SolrDocumentList sdList = resp.getResults();
long totalResults = sdList.getNumFound();//命中的总记录数
log.info("totalResults-->"+totalResults);
for(SolrDocument sd:sdList){
Collection strs = sd.getFieldNames();
log.info(sd.getFieldValue("title"));
log.info(sd.getFieldValue("content"));
Object id = sd.getFieldValue("id");
if(resp.getHighlighting().get(id)!=null){
log.info("高亮的结果-->"
+resp.getHighlighting().get(id).get("content"));
}
log.info("-------------------------------");
}
} catch (SolrServerException e) {
e.printStackTrace();
}
}
/**
* 将对象集合添加至索引
* @param lists 自定义转换机制
*/
public static void addConvertBeans(List lists){
try {
HttpSolrServer server = getSolrServer();
server.add(entityList2SolrInputDocument(lists));
server.commit(false, false);
log.info("Add convert object list to index finished. ");
} catch (Exception e) {
log.error("Add convert object list to index error, " + e.getMessage(), e);
}
}
/**
* 将对象集合添加至索引
* @param lists 自定义转换机制
*/
public static void addConvertBean(Object obj){
try {
HttpSolrServer server = getSolrServer();
server.add(entity2SolrInputDocument(obj));
server.commit(false, false);
log.info("Add convert object to index finished. ");
} catch (Exception e) {
log.error("Add convert object to index error, " + e.getMessage(), e);
}
}
public static Iterator entityList2SolrInputDocument(List lists){
List list = new ArrayList();
for(T obj : lists){
list.add(entity2SolrInputDocument(obj));
}
return list.iterator();
}
/**
* 实体类与SolrInputDocument转换
* @param obj 实体对象
* @return SolrInputDocument SolrInputDocument对象
*/
public static SolrInputDocument entity2SolrInputDocument(Object obj) {
if (obj != null) {
Class> cls = obj.getClass();
Field[] filedArrays = cls.getDeclaredFields(); //获取类中所有属性
Method m = null;
SolrInputDocument sid = new SolrInputDocument();
for (Field f : filedArrays) {
//因为如果对象序列化之后,会增加该属性,不用对该属性进行反射
if(!f.getName().equals("serialVersionUID")){
try {
Object o = BeanUtils.getFieldValue(obj, f.getName());
/*//第二种方式根据get方法取属性值
* m = BeanUtils.getGetter(cls, f);
//属性名,与对应的属性值 get方法获取到的值
log.info(f.getName() + ":" + m.invoke(obj));*/
log.info(f.getName() + ":" + o);
sid.addField(""+ f.getName(), o);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return sid;
}
log.warn("Object to convert is null.");
return null;
}
/**
* 根据id从索引中删除记录
* @param idName 主键名
* @param id 主键值
*/
public static void deleteById(String idName, Object id){
try {
HttpSolrServer server = getSolrServer();
server.deleteByQuery(idName + ":" + id.toString());
server.commit(false, false);
log.info("Delete from index by id" + id + " finished . operate param is:" + idName + ":" + id.toString());
} catch (Exception e) {
log.error("Delete from index by id" + id + " error, " + e.getMessage(), e);
}
}
/**
* 根据id集合从索引中删除记录
* @param ids
*/
public static void deleteByIds(String idName,List ids){
try {
HttpSolrServer server = getSolrServer();
if (ids.size() > 0) {
StringBuffer query = new StringBuffer(idName + ":" + ids.get(0));
for (int i = 1; i < ids.size(); i++) {
if (null != ids.get(i)) {
query.append(" OR " + idName + ":" + ids.get(i).toString());
}
}
server.deleteByQuery(query.toString());
server.commit(false, false);
log.info("Delete from index by id list" + ids + " finished .");
}else{
log.info("Delete ids list is null.");
}
} catch (Exception e) {
log.error("Delete from index by id list" + ids + " error, " + e.getMessage(), e);
e.printStackTrace();
}
}
/**
* 根据查询从索引中删除
* @param queryString
*/
public static void deleteByQuery(String query){
try {
HttpSolrServer server = getSolrServer();
server.deleteByQuery(query);
server.commit(false, false);
log.info("Delete from index by query string " + query + "finished .");
} catch (Exception e) {
log.error("Delete from index by query Strng " + query + "error, " + e.getMessage(), e);
}
}
/**
* 删除所有索引
*/
public static void deleteAllIndex(){
try {
HttpSolrServer server = getSolrServer();
server.deleteByQuery("*:*");
server.commit(false, false);
log.info("All index delete finished.");
} catch (Exception e) {
log.error("Delete all index error " + e.getMessage(), e);
e.printStackTrace();
}
}
/**
* 根据关键字查询 [使用 solr内部转换机制]
* @param
* @param solrql sql查询串
* @param clzz 对象类型
* @return
*/
public static Page query(String solrql,Page page, Class clzz){
HttpSolrServer server = getSolrServer();
SolrQuery query = new SolrQuery();
query.setQuery(solrql);
query.setStart(page.getStartRow());
query.setRows(page.getPageSize());
QueryResponse response = null;
try {
response = server.query(query);
} catch (SolrServerException e) {
log.error("查询报错:"+e.getMessage());
return null;
}
//查询到的记录总数
int totalRow = Long.valueOf(response.getResults().getNumFound()).intValue();
//查询结果集
List items = response.getBeans(clzz);//转换成带有solr注解字段的bean
page.setTotalRecordsNo(totalRow);
page.setItems(items);
//填充page对象
return page;
}
/**
* 根据关键字查询
* @param solrql
* @param page
* @param hlField
* @param preTag 例如:("");//渲染标签
* @param postTag 例如: ("");//渲染标签
* @param clzz
* @param idName 主键,一般默认为id
* @return
*/
public static Page queryHighter(String solrql,Page page,List hlField,
String preTag,String postTag,Class clzz,String idName){
HttpSolrServer server = getSolrServer();
SolrQuery query = new SolrQuery();
query.setQuery(solrql);
//设置高亮显示
query.setHighlight(true);
//添加高亮域
for(String hlf : hlField){
query.addHighlightField(hlf);
}
//渲染标签
query.setHighlightSimplePre(preTag);
query.setHighlightSimplePost(postTag);
//分页查询
query.setStart(page.getStartRow());
query.setRows(page.getPageSize());
QueryResponse response = null;
try {
response = server.query(query);
} catch (SolrServerException e) {
e.printStackTrace();
return null;
}
//查询到的记录总数
int totalRow = Long.valueOf(response.getResults().getNumFound()).intValue();
//查询结果集
List items = new ArrayList();
//查询结果集
SolrDocumentList solrDocuments = response.getResults();
try {
Object obj = null;
Method m = null;
Class> fieldType = null;
Map>> highlightMap=response.getHighlighting();
for(SolrDocument solrDocument : solrDocuments) {
obj = clzz.newInstance();
Collection fieldNames = solrDocument.getFieldNames(); //得到所有的属性名
for (String fieldName : fieldNames) {
//需要说明的是返回的结果集中的FieldNames()比类属性多
Field[] filedArrays = clzz.getDeclaredFields(); //获取类中所有属性
for (Field f : filedArrays) {
//如果实体属性名和查询返回集中的字段名一致,填充对应的set方法
if(f.getName().equals(fieldName)){
//获取到的属性名
f = clzz.getDeclaredField(fieldName);
//属性类型
fieldType = f.getType();
//获取set方法
m = BeanUtils.getSetter(clzz, f);
//获取fieldType类型
fieldType = getFileType(fieldType);
//获取到的值
// log.info(f.getName() + "-->=" + fieldType.cast(solrDocument.getFieldValue(fieldName)));
//获取到的属性
m.invoke(obj, fieldType.cast(solrDocument.getFieldValue(fieldName)));
for(String hl : hlField){
if(hl.equals(fieldName)){
String idv = solrDocument.getFieldValue(idName).toString();
List hlfList=highlightMap.get(idv).get(fieldName);
if(null!=hlfList && hlfList.size()>0){
//高亮添加
m.invoke(obj, fieldType.cast(hlfList.get(0)));
}else{
//正常添加
m.invoke(obj, fieldType.cast(solrDocument.getFieldValue(fieldName)));
}
}
}
}
}
}
items.add(clzz.cast(obj));
}
} catch (Exception e) {
log.error("highlighter query error." + e.getMessage(), e);
}
page.setTotalRecordsNo(totalRow);
page.setItems(items);
//填充page对象
return page;
}
public static Class> getFileType(Class> fieldType){
// 如果是 int, float等基本类型,则需要转型
if (fieldType.equals(Integer.TYPE)) {
return Integer.class;
} else if (fieldType.equals(Float.TYPE)) {
return Float.class;
} else if (fieldType.equals(Double.TYPE)) {
return Double.class;
} else if (fieldType.equals(Boolean.TYPE)) {
return Boolean.class;
} else if (fieldType.equals(Short.TYPE)) {
return Short.class;
} else if (fieldType.equals(Long.TYPE)) {
return Long.class;
} else if(fieldType.equals(String.class)){
return String.class;
}else if(fieldType.equals(Collection.class)){
return Collection.class;
}else if(fieldType.equals(List.class)){
return List.class;
}
return null;
}
public static void formatPrint(Page page,String solrql,Class clzz){
System.out.println("查询: " + solrql
+ "\t\t页码" + page.getCurrentPage()
+ "/" + page.getTotalPages()
+ ",总共找到" + page.getTotalRecordsNo()+"条符合的记录.\n");
List list = BeanUtils.getDeclaredFields(clzz);
for(Object qz: page.getItems()){
for(Field field : list){
try {
System.out.println(field.getName()+":" + BeanUtils.getFieldValue(qz,field.getName()));
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args){
SolrBase.deleteAllIndex();
/*
List msgs = new ArrayList();
for(int i=100006;i<100010;i++){
Message msg = new Message();
msg.setContent("我爱中国,我是中国人"+i);
msg.setId(i+"");
msg.setTitle("我爱中国,我是中国人,我有内容"+i);
msg.setUrl("http://localhost/ab"+i+".html");
msgs.add(msg);
Message msg1 = new Message();
msg1.setContent("广东某工作区内容");
msg1.setId("100012");
msg1.setTitle("广东某工作区内容");
msg1.setUrl("http://localhost/广东.html");
msgs.add(msg1);
}
SolrBase.addIndexByList(msgs);
System.out.print("创建索引成功");*/
/*Page page = new Page();
page.setPageSize(10);
page.setCurrentPage(1);
String solrql = "text:中国";
List hlField = new ArrayList();
hlField.add("title");
hlField.add("content");
SolrBase.queryHighter(solrql, page, hlField, "", "", Message.class, "id");
formatPrint(page,solrql);*/
}
}