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

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

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

   <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="title" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<field name="description" type="text_ik" indexed="true" stored="true"/>
<field name="author" type="text_ik" indexed="true" stored="true"/>
<field name="keywords" type="text_ik" indexed="true" stored="true"/>

Ik分词器定义如下

    <!--定义IK分词类型-->
<fieldType name="text_ik" class="solr.TextField">
<!--索引时候的分词器-->
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<!--查询时候的分词器-->
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>

2. 编写solr操作类SearchEngine.java,solrJ操作索引参看文章: http://www.cnblogs.com/dennisit/p/3623974.html3.这里演示solrj搜索高亮

/**
* solrJ搜索 高亮显示
*
* @author pudongping
*
* @param server
* solr客户端
* @param queryString
* 查询串
* @param pageNum
* 分页 页码
* @param pageSize
* 每页显示大小
* @return
*/
public static Page<QzoneArticle> 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("<font color='red'>");//渲染标签
query.setHighlightSimplePost("</font>");//渲染标签
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<QzoneArticle> items = new ArrayList<QzoneArticle>(); //查询到的记录总数
long totalRow = Long.valueOf(response.getResults().getNumFound()).intValue(); String tmpId = ""; Map<String,Map<String,List<String>>> 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<String> descList=highlightMap.get(tmpId).get("description");
List<String> 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<QzoneArticle>(pageNum, pageSize, totalRow, items); }

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

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

    /**
* 根据关键字查询 [测试通过 - 使用 solr内部转换机制]
* @param <T>
* @param server solr客户端
* @param keyword 搜索关键字
* @param pageNum 当前页码
* @param pageSize 每页显示的大小
* @param clzz 对象类型
* @return
*/
public static <T>Page<T> queryHighter(SolrServer server,String solrql,
int pageNum,int pageSize,List<String> hlField, String preTag,String postTag,Class<T> 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<T> items = new ArrayList<T>(); //查询结果集
SolrDocumentList solrDocuments = response.getResults();
try {
Object obj = null;
Method m = null;
Class<?> fieldType = null;
Map<String,Map<String,List<String>>> highlightMap=response.getHighlighting();
for(SolrDocument solrDocument : solrDocuments) {
obj = clzz.newInstance();
Collection<String> 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<String> 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<T>(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<QzoneArticle> lists = new ArrayList<QzoneArticle>();
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<String> ids = new ArrayList<String>();
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<String> hlFields = new ArrayList<String>();
hlFields.add("description");
hlFields.add("keywords");
String preTag = "<font color='red'>";
String postTag = "</font>";
Page<QzoneArticle> page = SearchEngine.queryHighter(server,solrql , 1, 10, hlFields, preTag, postTag, QzoneArticle.class, "id");
formatPrint(page, solrql);
} //测试通过
@Test
public void qzoneCommonHLQuery(){
String solrql = "description:文字";
Page<QzoneArticle> page = SearchEngine.queryComHighlight(server, solrql , 1, 10);
formatPrint(page, solrql);
} @Test
public void qzoneQuery(){
String solrql = "文字";
Page<QzoneArticle> 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<QzoneArticle> 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条符合的记录.

作者:林云熙
描述:<font color='red'>文字</font>控,我无悔,纵是情殇离人泪
关键字:<font color='red'>文字</font> 作者:苏若年
描述:Java程序猿, 爱音乐,爱生活,爱<font color='red'>文字</font>
关键字:Java,音乐,生活,<font color='red'>文字</font>

一个Solr搜索实例,增删改查+高亮+分页的更多相关文章

  1. 自己写的一个Solr搜索实例,增删改查+高亮+分页

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

  2. SpringBoot-Vue实现增删改查及分页小DEMO

    前言 主要通过后端 Spring Boot 技术和前端 Vue 技术来简单开发一个demo,实现增删改查.分页功能以及了解Springboot搭配vue完成前后端分离项目的开发流程. 开发栈 前端 开 ...

  3. 一个使用MVC3+NHibernate “增删改查” 的项目

    一个使用MVC3+NHibernate “增删改查” 的项目  前言: 谈到NHibernate大伙并不陌生,搞Java的更是清楚,Hibernate是一个目前应用的最广泛的开放源代码的对象关系映射框 ...

  4. 【讲义提纲】以一个实战新闻cms增删改查demo为例,给学院国创队伍培训php

    PHP实战基础——以一个新闻cms的增删改查为例 一.        环境配置 二.        数据库创建 三.        增删改查demo 连接数据库 <?php $link=mysq ...

  5. Online Coding开发模式 (通过在线配置实现一个表模型的增删改查功能,无需写任何代码)

    JEECG 智能开发平台. 开发模式由代码生成器转变为Online Coding模式                      (通过在线配置实现一个表模型的增删改查功能,无需一行代码,支持用户自定义 ...

  6. 用SpringBoot+MySql+JPA实现对数据库的增删改查和分页

    使用SpringBoot+Mysql+JPA实现对数据库的增删改查和分页      JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述 ...

  7. SpringBoot JPA实现增删改查、分页、排序、事务操作等功能

    今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查.分页.排序.事务操作等功能.下面先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 SQL 中的 and ...

  8. Magicodes.WeiChat——ASP.NET Scaffolding生成增删改查、分页、搜索、删除确认、批量操作、批量删除等业务代码

    关于T4代码生成这块,我之前写过几篇帖子,如:<Magicodes.NET框架之路——让代码再飞一会(ASP.NET Scaffolding)>(http://www.cnblogs.co ...

  9. 一个使用MVC3+NHibernate “增删改查” 的项目(修正版)

      前言: 谈到NHibernate大伙并不陌生,搞Java的更是清楚,Hibernate是一个目前应用的最广泛的开放源代码的对象关系映射框架,它对Java的JDBC(类似于ADO.Net)进行了非常 ...

随机推荐

  1. php 生成类的对象 $a=new test();

    程序 <?php class test { ... } $a=new test(); 1.BNF 范式 start: variable '=' expr ';' expr: new_expr ; ...

  2. Unity3D GUI中的图片跟随鼠标旋转脚本

    var Mid : Texture2D; var mouse : Texture2D; //鼠标图片 var mousePs = Vector2.zero; //鼠标的位置 private var a ...

  3. ehcache 分布式集群同步数据实例

    本文使用rmi方式,借鉴百度能搜到的文章,但是均不能做到数据同步,做了些改动完全没问题,更详细说明介绍百度即可.直奔主题,可运行的demo实例! 创建一个maven项目,配置pom pom.xml & ...

  4. 装饰器模式(Decorator)

    转自http://blog.csdn.net/hust_is_lcd/article/details/7884320 1.认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象 ...

  5. Application Pool Identities

    Whether you are running your site on your own server or in the cloud, security must be at the top of ...

  6. 数学(扩展欧几里得算法):HDU 5114 Collision

    Matt is playing a naive computer game with his deeply loved pure girl. The playground is a rectangle ...

  7. 《深入Java虚拟机学习笔记》- 第9章 垃圾收集

    一.Java内存组成 组成图 堆(Heap) 运行时数据区域,所有类实例和数组的内存均从此处分配.Java虚拟机启动时创建.对象的堆内存由称为垃圾回收器的自动内存管理系统回收. 组成 组成 详解 Yo ...

  8. 【工具类】如何通过代码安装一个apk文件

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  9. Apache-AB压力测试实例

    一 AB背景介绍 Apache附带的压力测试工具apache bench--简称ab,非常容易使用,并且完全可以摸你各种条件对Web服务器发起测试请求.ab可以直接在Web服务器本地发起测试请求,这对 ...

  10. JAVACC详解

    JavaCC(Java Compiler Compiler)是一个用JAVA开发的最受欢迎的语法分析生成器.这个分析生成器工具可以读取上下文无关且有着特殊意义的语法并把它转换成可以识别且匹配该语法的J ...