博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个Solr搜索实例,增删改查+高亮+分页
阅读量:7259 次
发布时间:2019-06-29

本文共 9867 字,大约阅读时间需要 32 分钟。

今天个人coding的模块测试,所以闲暇之余继续研究solr,然后顺带写了一个实例,随便搞的,solr真心不熟,期待认识热爱搜索的朋友,共同进步.

1.配置schema.xml文件[solr\collection1\conf\目录下]

因为schema默认定义了一些Field,我们这里选取[id,title,description, author]这几个属性,将id主键type配置为string,其它几个type配置为自定义的ik分词器

Ik分词器定义如下

2. 编写solr操作类SearchEngine.java,solrJ操作索引参看文章: 3.这里演示solrj搜索高亮

/**     * solrJ搜索 高亮显示      *      * @author pudongping     *      * @param server     *                     solr客户端     * @param queryString     *                     查询串     * @param pageNum     *                     分页 页码     * @param pageSize     *                     每页显示大小     * @return     */    public static Page
queryComHighlight(SolrServer server, String queryString, int pageNum,int pageSize){ SolrQuery query = new SolrQuery(); query.setQuery(queryString); query.setHighlight(true);//开启高亮功能 query.addHighlightField("description");//高亮字段 query.addHighlightField("keywords"); query.setHighlightSimplePre("
");//渲染标签 query.setHighlightSimplePost("");//渲染标签 query.setStart((pageNum-1)*pageSize); query.setRows(pageSize); QueryResponse response = null; try { response = server.query(query); } catch (SolrServerException e) { e.printStackTrace(); return null; } //查询结果集 SolrDocumentList lists = response.getResults(); //对象结果集 List
items = new ArrayList
(); //查询到的记录总数 long totalRow = Long.valueOf(response.getResults().getNumFound()).intValue(); String tmpId = ""; Map
>> highlightMap=response.getHighlighting(); for (SolrDocument solrDocument : lists) { QzoneArticle at = new QzoneArticle(); tmpId=solrDocument.getFieldValue("id").toString(); at.setId(tmpId); at.setAuthor(solrDocument.getFieldValue("author").toString()); List
descList=highlightMap.get(tmpId).get("description"); List
keywsList=highlightMap.get(tmpId).get("keywords"); if(descList!=null && descList.size()>0){ at.setDescription(descList.get(0)); }else{ //获取并设置高亮的字段title at.setDescription(solrDocument.getFieldValue("description").toString()); } if(keywsList!=null && keywsList.size()>0){ at.setKeywords(keywsList.get(0)); }else{ at.setKeywords(solrDocument.getFieldValue("keywords").toString()); } items.add(at); } //填充page对象 return new Page
(pageNum, pageSize, totalRow, items); }

搜索高亮是找到关键字所在的记录域,然后追加前后缀,重新填充到对象,这里拆开来将是两个步骤,第一步设置高亮域,第二步查询结果追加渲染标记,填充到对象.所以这个可以抽取出来写成一个公用的方法

4.抽取高亮操作,实现公用方法

/**     * 根据关键字查询 [测试通过 - 使用 solr内部转换机制]     * @param 
* @param server solr客户端 * @param keyword 搜索关键字 * @param pageNum 当前页码 * @param pageSize 每页显示的大小 * @param clzz 对象类型 * @return */ public static
Page
queryHighter(SolrServer server,String solrql, int pageNum,int pageSize,List
hlField, String preTag,String postTag,Class
clzz,String idName){ 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((pageNum-1)*pageSize); query.setRows(pageSize); QueryResponse response = null; try { response = server.query(query); } catch (SolrServerException e) { e.printStackTrace(); return null; } //查询到的记录总数 long 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)){ //获取到的属性名 //private java.lang.String com.test.model.Article.id f = clzz.getDeclaredField(fieldName); //属性类型 //private java.lang.String com.test.model.Article.id fieldType = f.getType(); //构造set方法名 setId String dynamicSetMethod = dynamicMethodName(f.getName(), "set"); //获取方法 //public void com.test.model.Article.setId(java.lang.String) m = clzz.getMethod(dynamicSetMethod, fieldType); //获取到的值 LOG.info(f.getName() + "-->" + dynamicSetMethod+ "=" + fieldType.cast(solrDocument.getFieldValue(fieldName))); //获取fieldType类型 fieldType = getFileType(fieldType); //获取到的属性 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); e.printStackTrace(); } //填充page对象 return new Page
(pageNum, pageSize, totalRow, items); } 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; } return null; }

需要说明的是,这里的方法定义并不是很完善,因为反射的属性可能是一个集合,所以在利用反射转换之前,需要进行更精确地判断,这实例中实体对象中的属性为简单类型,所以这个方法可以处理.

5.junit测试

package com.test.search;import java.util.ArrayList;import java.util.List;import java.util.UUID;import org.apache.solr.client.solrj.SolrServer;import org.junit.Before;import org.junit.Test;import com.plugin.page.Page;import com.plugin.solr.client.SolrClient;import com.plugin.solr.engine.SolrEngineHandler;import com.test.model.QzoneArticle;public class SolrTest {    private SolrServer server;        @Before    public void init(){        String solrURL = "http://localhost:8888/solr";         server = SolrClient.getHttpSolrServer(solrURL);    }        @Test    public void qzoneAdd(){        List
lists = new ArrayList
(); QzoneArticle qz1 = new QzoneArticle(); qz1.setId(UUID.randomUUID().toString()); qz1.setAuthor("苏若年"); qz1.setDescription("Java程序猿, 爱音乐,爱生活,爱文字"); qz1.setKeywords("Java,音乐,生活,文字"); QzoneArticle qz2 = new QzoneArticle(); qz2.setId(UUID.randomUUID().toString()); qz2.setAuthor("林云熙"); qz2.setDescription("文字控,我无悔,纵是情殇离人泪"); qz2.setKeywords("文字"); lists.add(qz1); lists.add(qz2); SearchEngine.addBeans(server, lists); } @Test public void qzoneDeLId(){ String id = "4f1b6b87-c824-4e38-a431-9a8f50e7af0c"; SolrEngineHandler.deleteById(server, "id", id); } @Test public void qzoneDeLIds(){ List
ids = new ArrayList
(); ids.add("d026e3ef-b89a-4ce2-9fbb-aa195ed2070b"); ids.add("9deb98ca-5a65-424d-95ad-91e87c2bde2c"); ids.add("5576650d-5517-43d5-987c-6d7135588e1f"); SolrEngineHandler.deleteByIds(server, "id", ids); } @Test public void qzoneDeLAll(){ SolrEngineHandler.deleteAllIndex(server); } @Test public void qzoneHLQuery(){ String solrql = "keywords:文字"; List
hlFields = new ArrayList
(); hlFields.add("description"); hlFields.add("keywords"); String preTag = "
"; String postTag = ""; Page
page = SearchEngine.queryHighter(server,solrql , 1, 10, hlFields, preTag, postTag, QzoneArticle.class, "id"); formatPrint(page, solrql); } //测试通过 @Test public void qzoneCommonHLQuery(){ String solrql = "description:文字"; Page
page = SearchEngine.queryComHighlight(server, solrql , 1, 10); formatPrint(page, solrql); } @Test public void qzoneQuery(){ String solrql = "文字"; Page
page = SearchEngine.query(server,solrql , 1, 10,QzoneArticle.class); formatPrint(page, solrql); } @Test public void qzoneUpdate(){ QzoneArticle qz = new QzoneArticle(); qz.setId("5576650d-5517-43d5-987c-6d7135588e1f"); qz.setAuthor("林云熙"); qz.setDescription("文字控,我无悔,纵是情殇离人泪"); qz.setKeywords("文字"); SearchEngine.updateBean(server, qz, "id"); } @Test public void pingSolr(){ System.out.println("ping solr result: " +SolrEngineHandler.ping(server)); } public void formatPrint(Page
page,String solrql){ System.out.println("查询: " + solrql + "\t\t页码" + page.getPageNum() + "/" + page.getTotalPage() + ",总共找到" + page.getTotalRow()+"条符合的记录.\n"); for(QzoneArticle qz: page.getItems()){ System.out.println("作者:" + qz.getAuthor()); System.out.println("描述:" + qz.getDescription()); System.out.println("关键字:" + qz.getKeywords() + "\n\n"); } } }

搜索结果集展示如下:

查询: keywords:文字        页码1/1,总共找到2条符合的记录.作者:林云熙描述:文字控,我无悔,纵是情殇离人泪关键字:文字作者:苏若年描述:Java程序猿, 爱音乐,爱生活,爱文字关键字:Java,音乐,生活,文字

转载地址:http://qrodm.baihongyu.com/

你可能感兴趣的文章
『MXNet』第十二弹_再谈新建计算节点
查看>>
JBoss 7 里一个EJB依赖其他jar的几种方式
查看>>
编译器的诞生[三]编译器设计概览【转】
查看>>
Spring里的FactoryBean和BeanFactory有啥区别?
查看>>
使用Dockerfile文件构建基于centOS系统的tomcat镜像
查看>>
Android service broadcast 动态 更新 UI 界面
查看>>
linux -- 视频尺寸-cif、2cif、dcif、D1、HD1、4D1
查看>>
PHP上传图片新组件swfupload
查看>>
android 4.1源码下载方法最新实例教程
查看>>
powerdesigner 设置自动增长列(identity)和默认值
查看>>
Python标准库05 存储对象 (pickle包,cPickle包)
查看>>
CGI知识
查看>>
【转】【WebService】.NET C# 创建WebService服务
查看>>
C语言冒泡排序
查看>>
关于两个时间(00:00:00)相加的实现方法
查看>>
led子系统【转】
查看>>
压缩感知——SP(subspace pursuit)重构算法前言翻译
查看>>
less11 属性合并
查看>>
手写快排模版
查看>>
Linux 之 NTP 服务 服务器
查看>>