网站全文检索--Solr

做CMS管理系统时,配置好模版(jetbrick-template),调用数据库取数据,一个页面上配置了多个数据源,会多次请求数据库,数据库连接一下子耗完,程序报错,这还是在本地开发环境,尝试设置增加数据库连接池大小后,刷新模版页面,出现数据库链接超时的机会减少了。但这不是解决此问题的根本办法。还有一个场景网站搜索时(全文检索),如果去查询数据库,当表中内容过大时会搜索延迟、无法响应等问题。

使用Solr,它会把内容缓存起来, Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

OK,进入正题,当我系统启动时,会把要缓存的内容加载到 Solr 中,新增内容时,把内容加载到solr,修改内容时删除再新增。配置好网站模版,用户访问网站时,模版引擎访问的是 Solr中的内容,这样减少了数据库请求,加快了网站响应速度。

以上是理论,下面给出网站代码和 Solr的安装(windows + java jdk1.7以上):

1.下载Solr并安装,我下载的是 solr-5.5.4 ,百度云下载链接:http://pan.baidu.com/s/1c2Ccp3q 密码:wrx6

2.解压solr-5.5.4到任意目录,我的放在D盘根目录,然后使用 win+r 键打开 dos 窗口,cd 到 solr目录,输入 1. 启动:bin\solr.cmd start  2. 停止:bin\solr.cmd stop 或bin\solr.cmd stop -all  3. 查看:bin\solr.cmd status,看下面截图 ,然后访问:http://localhost:8983/solr/index.html 



3.Solr需要新增实例,类似于新增一个数据库,数据放到这个数据库中,可以新增多个实例。在solr-5.5.4目录的server\solr 目录下新建一个文件夹,名称为实例名,在该目录复制 jcg 文件夹中的 confiig和data文件夹内容到自己新建的目录中,然后在 http://localhost:8983/solr/index.html  网站后台的 Core Admin 中新增实例,实例的名称和刚刚新建的实例文件夹名称一样。类似如---新建了数据库,那么再建一个表,存放具体的数据,在Solr中,是以XML文件的方式配置的,schema.xml,看不明白文字的看下面图片。我在网站新建了一个  xjxqzwfw 的实例 和 实例文件夹,把 jcg文件中的内容全部复制到 xjxqzwfw 目录。然后修改 conf 中的 schema.xml 配置文件(类似于修改表的字段,修改成自己系统的字段,查看 filed属性,这个设置可以自行百度)




我把该配置文件中的与我系统无关的  filed  字段 删除掉了,改成自己需要的


现在所有的服务配置就此完成,可以在网站后台去新增数据,查询数据,删除数据,这些操作可自行百度,我直接贴代码:

在我项目中新建一个java类,

package com.bus.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrInputDocument;

import com.cms.db.entity.CmsContentDto;
import com.sys.base.SpringContext;
import com.sys.util.common.DateTools;

public class SolrUtil {
	
	/**
	 * solr http服务地址
	 * 如:http://192.168.20.117:8983/solr
	 */
	private static String solr_url = "http://192.168.20.117:8983/solr";
	/**
	 * solr的core 实例
	 * 如:xjxqzwfw
	 */
	private static String solr_core = "xjxqzwfw";
	
	//测试
	public static void main(String[] args) throws Exception {
		List<CmsContentDto> contentDtos = new ArrayList<CmsContentDto>();
		CmsContentDto c1 = new CmsContentDto("01d291d75e7f4a94890a28fe67832d90","CHANNELI_1705011127060000","湖南湘江新区管委会召开首届职工代表大会3","","<p>湖南湘江新区管委会召开首届职工代表大会3</p>",new Date(),1L,"3503e9bf-7fba-395d-7096-ac104a189570",new Date(),"");
		CmsContentDto c2 = new CmsContentDto("1a2c139fd3e54688bac3bb58fa2b6188","CHANNELI_1705011127060000","湖南湘江新区管委会召开首届职工代表大会2","","<p>湖南湘江新区管委会召开首届职工代表大会2</p>",new Date(),1L,"59b5017eadbf4d44bff8184b2c7c3c20",new Date(),"");
		CmsContentDto c3 = new CmsContentDto("6867119e6d68489a95d6d9b0b6ff472e","CHANNELI_1705011127060000","湖南湘江新区管委会召开首届职工代表大会1","","<p>湖南湘江新区管委会召开首届职工代表大会1</p>",new Date(),1L,"8eda2823-70c8-dca5-2598-569df8852c2b",new Date(),"");
		contentDtos.add(c1);
		contentDtos.add(c2);
		contentDtos.add(c3);
		addDocumentByBeans(contentDtos); //把数据加载到 Solr中
		
		getListDocument(solr_core,"channelId:CHANNELI_1705011127060000",0,10); //查询数据,得到的结果可以打印到控制台
		//删除所有数据
		//HttpSolrClient solrClient = new HttpSolrClient("http://192.168.20.117:8983/solr/xjxqzwfw");
    	        //solrClient.deleteByQuery("*:*");
    	        //commitAndCloseSolr(solrClient);
	}
	
	/**
     * 获取solr服务
     * @return
     */
    private static HttpSolrClient getSolrClient() {
        HttpSolrClient hsc = new HttpSolrClient(solr_url +"/"+ solr_core);
        return hsc;
    }
    
    /**
     * 添加文档
     * @param map
     * @param core
     * @throws Exception
     */
    public static void addDocumentByMap(Map<String, String> map) throws Exception {
        SolrInputDocument sid = new SolrInputDocument();
        for (Entry<String, String> entry : map.entrySet()) {
            sid.addField(entry.getKey(), entry.getValue());
        }
        HttpSolrClient solrClient = getSolrClient();
        solrClient.add(sid);
        commitAndCloseSolr(solrClient);
    }
    
    /**
     * 添加文档,通过bean方式
     * @param persons
     * @param core
     * @throws Exception
     */
    public static void addDocumentByBean(CmsContentDto content) throws Exception {
        HttpSolrClient solrClient = getSolrClient();
        solrClient.addBean(content);
        commitAndCloseSolr(solrClient);
    }
    
    /**
     * 添加文档,通过bean方式
     * @param persons
     * @param core
     * @throws Exception
     */
    public static void addDocumentByBeans(List<CmsContentDto> contents) throws Exception {
        HttpSolrClient solrClient = getSolrClient();
        solrClient.addBeans(contents);
        commitAndCloseSolr(solrClient);
    }
    
    /**
     * 根据id删除索引
     * @param ids
     * @param core
     * @throws Exception
     */
    public static void deleteDocumentById(String id) throws Exception {
        HttpSolrClient solrClient = getSolrClient();
        solrClient.deleteById(id);
        commitAndCloseSolr(solrClient);
    }
    
    /**
     * 根据ids集合删除索引
     * @param ids
     * @param core
     * @throws Exception
     */
    public static void deleteDocumentByIds(List<String> ids) throws Exception {
        HttpSolrClient solrClient = getSolrClient();
        solrClient.deleteById(ids);
        commitAndCloseSolr(solrClient);
    }
    
    /**
     * 根据条件删除
     * @param query id:1
     * @throws Exception
     */
    public static void deleteDocumentByQuery(String query)throws Exception{
    	HttpSolrClient solrClient = getSolrClient();
    	solrClient.deleteByQuery(query);
    	commitAndCloseSolr(solrClient);
    }
    
    /**
     * 删除所有索引
     * @throws Exception
     */
    public static void delteteDocumentAll() throws Exception{
    	HttpSolrClient solrClient = getSolrClient();
    	solrClient.deleteByQuery("*:*");
    	commitAndCloseSolr(solrClient);
    }
    
    /**
     * 根据id获取内容
     * @param id
     * @return
     * @throws Exception
     */
    public static CmsContentDto getDocumentById(String id) throws Exception{
    	CmsContentDto contentDto = null;
    	HttpSolrClient solrClient = getSolrClient();
    	SolrDocument doc = solrClient.getById(id);
    	if(doc != null && !doc.get("id").equals("")){
    		contentDto = new CmsContentDto();
    		contentDto.setId(doc.get("id").toString());
    		contentDto.setChannelId(doc.get("channelId").toString());
    		contentDto.setTitle(doc.get("title").toString());
    		contentDto.setContent(doc.get("content").toString());
    		contentDto.setPublishTime(DateTools.strToDate(doc.get("publishTime").toString(), "yyyy-MM-dd HH:mm:ss"));
    		contentDto.setIsPublish(1L);
    		contentDto.setAttachmentPath(doc.get("attachmentPath").toString());
    		contentDto.setAttachPath(doc.get("attachPath").toString());
    		contentDto.setCreateDate(DateTools.strToDate(doc.get("createDate").toString(), "yyyy-MM-dd HH:mm:ss"));
    	}
    	commitAndCloseSolr(solrClient);
    	return contentDto;
    }
    
    /**
     * 查询文档内容集合
     * @param core 实例名
     * @param channelId 查询条件 (查询所有:*:* )(查询channelId下的文章:channelId:CHANNELI_1705011127060000)
     * @param filterQuery 其他过滤条件 (如:title:test1)
     * @param start 开始位置,0
     * @param rows  查询多少条,10
     * @param sortName  排序字段,默认:publishTime
     * @param order 升序降序,默认降序:SolrQuery.ORDER.desc
     * @throws Exception
     */
    public static List<CmsContentDto> getListDocument(String channelId ,String filterQuery,Integer start, Integer rows , String sortName , ORDER order) throws Exception {
        HttpSolrClient solrClient = getSolrClient();
        SolrQuery sq = new SolrQuery();

        // q查询
        sq.set("q", "channelId:" + channelId);
        // filter查询
        if(filterQuery != null && !filterQuery.equals("")){
        	sq.addFilterQuery(filterQuery);
        }
        // 排序
        if(sortName != null && !sortName.equals("")){
        	sq.setSort(sortName, order);
        }else{
        	sq.setSort("publishTime", SolrQuery.ORDER.desc);
        }
        // 分页 从第0条开始取,取一条
        sq.setStart(start);
        sq.setRows(rows);

        // 设置高亮
        //sq.setHighlight(true);
        // 设置高亮的字段
        //sq.addHighlightField("name");
        // 设置高亮的样式
        //sq.setHighlightSimplePre("<font color='red'>");
        //sq.setHighlightSimplePost("</font>");

        QueryResponse result = solrClient.query(sq);

        // 这里可以从result获得查询数据(两种方式如下)
        // 1.获取document数据
        //System.out.println("1.获取document数据-------------------------");
        //SolrDocumentList results = result.getResults();
        // 获取查询的条数
        //System.out.println("一共查询到" + results.getNumFound() + "条记录");
        /*for (SolrDocument solrDocument : results) {
            System.out.println("id:" + solrDocument.get("id"));
            System.out.println("name:" + solrDocument.get("name"));
            System.out.println("age:" + solrDocument.get("age"));
            System.out.println("addr:" + solrDocument.get("addr"));
        }*/

        // 2.获取对象信息,需要传入对应对象的类class
        List<CmsContentDto> contents = result.getBeans(CmsContentDto.class);
        commitAndCloseSolr(solrClient);
        return contents;
    }
    
    /**
     * 提交以及关闭服务
     * @param solrClient
     * @throws Exception
     */
    private static void commitAndCloseSolr(HttpSolrClient solrClient)
            throws Exception {
        solrClient.commit();
        solrClient.close();
    }
}

需要的jar包,百度云链接: http://pan.baidu.com/s/1bX4MAi  密码:uxat

部署在windows server服务器上,写一个bat的文件,把命令写入到bat中,再创建一个快捷方式,把快捷方式拖入到windows启动中,它会跟随服务器启动时自动启动,
bat文件中的命令:
D:
cd D:\solr-5.5.4
bin\solr.cmd start
我通过以上命令,在cmd窗口中启动solr,但是服务器重启后就不会再运行了,那么需要一个跟随服务器自动启动的命令

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值