文档章节

全文检索可视化动态管理(二)--solr二次开发和solrj扩展

hxt168
 hxt168
发布于 2016/07/12 15:06
字数 1589
阅读 235
收藏 8
点赞 0
评论 0

  要完成solr的索引动态配置,需要solr提供动态新建、修改配置等的接口。solr虽提供core的添加删除,但不提供schema.xml修改新建接口,并且如果添加一个新core,也要将另一个core的conf配置文件复制一份到新的core文件夹下,然后管理页载入新的core。因此需要二次开发。
   查看solr的web.xml,可以发现请求链接都进入org.apache.solr.servlet.SolrDispatchFilter。查看SolrDispatchFilter源码,可以在doFilter方式里看到,如果是adminPath的链接,则SolrRequestHandler的实现是cores.getMultiCoreHandler()。 

进入getMultiCoreHandler()方法,可以得知是org.apache.solr.handler.admin.CoreAdminHandler。此类则是solr管理界面的Core Admin的接口处理类。因此,可以继承CoreAdminHandler,重载handleRequestBody方法来给solr增加所需的处理接口。

    进一步查看源码,可以发现solr.xml里可以用adminHandler标签替换CoreAdminHandler。solr.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<solr persistent="true">
  <cores defaultCoreName="default" adminHandler="org.apache.solr.handler.admin.EdenCoreAdminHandler" adminPath="/admin/cores" zkClientTimeout="${zkClientTimeout:15000}" hostPort="8080" hostContext="solr">
    <core instanceDir="core0\" name="core0"/>
    <core instanceDir="default\" name="default"/>
    <core instanceDir="periodical\" name="periodical"/>

  </cores>
</solr>

EdenCoreAdminHandler:

public class EdenCoreAdminHandler  extends CoreAdminHandler {

	  public EdenCoreAdminHandler()
	  {
		  
		 
	  }
	  
	 public EdenCoreAdminHandler(final CoreContainer coreContainer) {
		    super(coreContainer);
	}
	 
	  public CoreContainer getCoreContainer() {
		    return this.coreContainer;
		  }
	 
	
	@Override
	public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)
			throws Exception {
		  CoreContainer cores = getCoreContainer();
		    if (cores == null) {
		      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
		              "Core container instance missing");
		    }
		    String action = req.getParams().get(CoreAdminParams.ACTION);
			//String newCoreName=req.getParams().get("newCoreName");
			if (action!=null&&action.equals("ADDNEWCORE")) {
				doAddCore( req,  rsp);
			}else if (action!=null&&action.equals("CHANGESCHEMA")) {
				changeSchemaXml(req, rsp);
			}else if (action!=null&&action.equals("DELCORE")) {
				delCore(req, rsp);
			}else{
				super.handleRequestBody( req, rsp);
			}
        
	}
	
	
	/**
	 * 添加core
     *将默认core下conf里的solrconfig.xml和schema.xml拷贝到新core的conf下。这步是必须的
     *因为新建的core solr会去其conf文件夹下找这两个文件,如果没有就会报错,新core则不会创建成功
	 * @param req
	 * @param rsp
	 * @throws Exception
	 */
	public void doAddCore(SolrQueryRequest req, SolrQueryResponse rsp)	throws Exception 
	{
		  CoreContainer cores = getCoreContainer();
		 
		String defaultCoreName=  cores.getDefaultCoreName();
		SolrCore core=cores.getCore(defaultCoreName);
		
		final SolrResourceLoader loader = core.getResourceLoader();
		File srcCoredir = new File(loader.getInstanceDir());

	
		if (!srcCoredir.exists()) {
			throw new SolrException(ErrorCode.FORBIDDEN,
					"当前core不存在!");
		}

		String newCoreName=req.getParams().get(CoreAdminParams.NAME);
		if (newCoreName==null||newCoreName.equals("")) {
			 
			 throw new SolrException(ErrorCode.FORBIDDEN,
						"name不能为空!");
		 }
		 if (coreContainer.getCore(newCoreName) != null) {
			 
			 throw new SolrException(ErrorCode.FORBIDDEN,
						"已经创建了"+newCoreName+"的core!");
		 }
			
		String solrHome=srcCoredir.getParent();
		String srcConfPath= solrHome+File.separator+"default"+ File.separator+"conf";  //复制default文件夹
		String fromCoreName=req.getParams().get(CoreAdminParams.OTHER);
		if(fromCoreName!=null&&!fromCoreName.equals(""))  //如果有参数,则用这个的配置
		{
			SolrCore fromcore=cores.getCore(fromCoreName);
			SolrResourceLoader fromcoreLoader = fromcore.getResourceLoader();
			srcConfPath=fromcoreLoader.getConfigDir();
			
		}
	
		  // 建立新core所在文件夹
       File newCorePath = new File(solrHome + File.separator + newCoreName);
       if (!newCorePath.exists()) {
    	   newCorePath.mkdir();
       }
       // 建立新core下的conf文件夹
       File newConfPath = new File(newCorePath.getAbsolutePath() + File.separator
               + "conf/");
       if (!newConfPath.exists()) {
    	   newConfPath.mkdir();
       }
  
       boolean doPersist=this.handleCreateAction(req, rsp);
       
       if (doPersist) {
           cores.persist();
           rsp.add("saved", cores.getConfigFile().getAbsolutePath());
         }
         rsp.setHttpCaching(false);
		
	}
	
	.......

	@Override
	public String getDescription() {
		return "add new core";
	}

	@Override
	public String getSource() {
		return null;
	}

}

 

同时solrj也要扩展新接口的请求方法。按照solrj源码里的请求方式。

EdenCoreAdminParams:

public class EdenCoreAdminParams implements CoreAdminParams{
	  public enum EdenCoreAdminAction {
	    CORESINFO,
	    ADDNEWCORE,
	    CHANGESCHEMA,
	    DELCORE;
	    public static CoreAdminAction get( String p )
	    {
	      if( p != null ) {
	        try {
	          return CoreAdminAction.valueOf( p.toUpperCase(Locale.ROOT) );
	        }
	        catch( Exception ex ) {}
	      }
	      return null; 
	    }
	  }
	
}

EdenSchemaUpdateRequest(动态修改schema.xml):

public class EdenSchemaUpdateRequest extends AbstractUpdateRequest{

	private String xmlContent=null;
	
	public EdenSchemaUpdateRequest( String path) {
		super(METHOD.POST, path);
	}

	@Override
	public Collection<ContentStream> getContentStreams() throws IOException {
		 return ClientUtils.toContentStreams(getXmlContent(), ClientUtils.TEXT_XML);
	}

	public String getXmlContent() {
		return xmlContent;
	}

	public void setXmlContent(String xmlContent) {
		this.xmlContent = xmlContent;
	}

	
}

EdenCoreAdminRequest:

/**
 *  solrj CoreAdminRequest扩展
 * @author hanxuetong
 * 
 */
@SuppressWarnings("serial")
public class EdenCoreAdminRequest extends CoreAdminRequest{

	protected  ModifiableSolrParams params;
    protected EdenCoreAdminAction edenAction; 
	
	
    @Override
    public SolrParams getParams() {
    	
        if(params==null)
        {
        	params = new ModifiableSolrParams(); 
        }
        if( edenAction == null&&params==null ) { //使用原来的
	        return super.getParams();
	    }
        if(edenAction==null||edenAction.equals(EdenCoreAdminAction.CORESINFO)  ) //直接查询所有信息
        {
        	 return params;
        }
        
        params.set( EdenCoreAdminParams.ACTION, edenAction.toString() );
        params.set( EdenCoreAdminParams.NAME, core );
    	if(other!=null)
    	{
    		params.set( EdenCoreAdminParams.OTHER, other );
    	}

      return params;
    }
	public void setParams(ModifiableSolrParams params) {
		this.params = params;
	}

	public void setEdenAction(EdenCoreAdminAction edenAction) {
		this.edenAction = edenAction;
	}
	 public static class DelCore extends EdenCoreAdminRequest {
		    protected String deleteDir;

		    public DelCore(String deleteDir) {
		      edenAction=EdenCoreAdminAction.DELCORE;
		      this.deleteDir = deleteDir;
		    }

		    public String isDeleteDir() {
		      return deleteDir;
		    }

		    public void setDeleteDir(String deleteDir) {
		      this.deleteDir = deleteDir;
		    }

		    @Override
		    public SolrParams getParams() {
		      ModifiableSolrParams params = new ModifiableSolrParams();
		      params.set( EdenCoreAdminParams.ACTION, edenAction.toString());
		      params.set( EdenCoreAdminParams.CORE, core );
		      if(deleteDir!=null)
		      {
		    	  params.set("deleteDir", deleteDir);
		      }
		     
		      return params;
		    }
	 }
	  public static CoreAdminResponse delCore( String name, String deleteDir, SolrServer server ) throws SolrServerException, IOException
	  {
		  DelCore req = new DelCore(deleteDir);
		  req.setCoreName( name );
		  return req.process( server );
	  }	 
}

EdenSolrCoresRequest:

/**
 * solr控制台管理交互类
 * @author hanxuetong
 * 
 */
public class EdenSolrCoresRequest {

	/**
	 * 获得所有core信息
	 * @return
	 * @throws IOException 
	 * @throws SolrServerException 
	 */
	public static NamedList<NamedList<Object>>  getSolrCoresInfo(HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		EdenCoreAdminRequest req = new EdenCoreAdminRequest();
	    req.setEdenAction( EdenCoreAdminAction.CORESINFO );
		CoreAdminResponse list = req.process( rootServer );
		
		NamedList<NamedList<Object>>  coresInfoList=list.getCoreStatus();

		return coresInfoList;
			
	}
	
	/**
	 * 获取某一core信息
	 * @param coreName
	 * @param rootServer
	 * @return
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static NamedList<Object>  getSolrOneCoreInfo(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		
		NamedList<Object> list = EdenCoreAdminRequest
				       .getStatus(coreName, rootServer)
				       .getCoreStatus()
				       .get(coreName);

		return list;
	}
	
	/**
	 * 添加core,默认
	 * @param newCoreName
	 * @param rootServer
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void addCore(String newCoreName,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		
		
		EdenCoreAdminRequest req = new EdenCoreAdminRequest();
		req.setCoreName(newCoreName);
		req.setEdenAction(EdenCoreAdminAction.ADDNEWCORE);
	
		CoreAdminResponse list = req.process(rootServer);
		int state = list.getStatus();
		if (state != 0) {
			throw new SolrServerException("添加core失败!");
		}

		
	}
	
	
	/**
	 * 添加core
	 * @param newCoreName
	 * @param from 复制的core配置
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void addCore(String newCoreName,String from,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		
		
		EdenCoreAdminRequest req = new EdenCoreAdminRequest();
		req.setCoreName(newCoreName);
		req.setEdenAction(EdenCoreAdminAction.ADDNEWCORE);
		req.setOtherCoreName(from);
		CoreAdminResponse list = req.process(rootServer);
		int state = list.getStatus();
		if (state != 0) {
			throw new SolrServerException("添加core失败!");
		}

		
	}
	
	/**
	 * 获取schema.xml内容
	 * @param coreName
	 * @param rootServer
	 * @return
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static String getSchemaXmlContent(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		ModifiableSolrParams params = new ModifiableSolrParams();
		params.set("file", "schema.xml");
		params.set("contentType", "text/xml;charset=utf-8");
		EdenCoreAdminRequest req = new EdenCoreAdminRequest();
		req.setPath("/" + coreName + "/admin/file");
		req.setParams(params);
		NamedList<Object> ob = rootServer.request(req, null);
		InputStream respBody = (InputStream) ob.get("stream");
		String con=StringStreamUtil.convertStreamToString(respBody);
				
		return con;
	}
	
	/**
	 * 远程修改schema.xml的内容
	 * @param coreName
	 * @param xmlContent
	 * @param rootServer
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void postSchemaXmlContent(String coreName,String xmlContent,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
	
		EdenSchemaUpdateRequest edenSchemaUpdateRequest=new EdenSchemaUpdateRequest("/admin/cores");
	    edenSchemaUpdateRequest.setParam("name", coreName);
	    edenSchemaUpdateRequest.setParam("action", "CHANGESCHEMA");
	    edenSchemaUpdateRequest.setXmlContent(xmlContent);	  
	    UpdateResponse rep=edenSchemaUpdateRequest.process(rootServer);
	    int state =  rep.getStatus();
		if (state != 0) {
			throw new SolrServerException("postSchemaXml失败!");
		}
		
	}
	
	/**
	 * 重新加载core
	 * @param coreName
	 * @param rootServer
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void reloadCore(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		CoreAdminRequest req = new CoreAdminRequest();
		req.setAction(CoreAdminAction.RELOAD);
		req.setCoreName(coreName);
		CoreAdminResponse list = req.process(rootServer);
		int state = list.getStatus();
		if (state != 0) {
			throw new SolrServerException("reload失败!");
		}
		
		
	}
	
	/***
	 * 加载core
	 * @param coreName
	 * @param rootServer
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void loadCore(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		CoreAdminRequest req = new CoreAdminRequest();
		req.setAction(CoreAdminAction.LOAD);
		req.setCoreName(coreName);
		CoreAdminResponse list = req.process(rootServer);
		int state = list.getStatus();
		if (state != 0) {
			throw new SolrServerException("load失败!");
		}
		
		
	}
	
	/**
	 * 删除core
	 * @param coreName
	 * @param isDeleteDir 是否删除文件夹
	 * @param rootServer
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void delCore(String coreName,boolean isDeleteDir,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		String instanceDir=null;
		if(isDeleteDir)
		{
			NamedList<Object> list = EdenCoreAdminRequest
				       .getStatus(coreName, rootServer)
				       .getCoreStatus()
				       .get(coreName);
			instanceDir=(String) list.get("instanceDir");
		}
		
	
		int state= EdenCoreAdminRequest
			       .delCore(coreName, instanceDir, rootServer)
			       .getStatus();
		if (state != 0) {
			throw new SolrServerException("delCore失败!");
		}
		
		
	}
	
	/**
	 * 两个core交换
	 * @param coreName
	 * @param otherCore
	 * @param rootServer
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public static void swap(String coreName,String otherCore,HttpSolrServer rootServer) throws SolrServerException, IOException
	{
		CoreAdminRequest req = new CoreAdminRequest();
		req.setAction(CoreAdminAction.SWAP);
		req.setCoreName(coreName);
		req.setOtherCoreName(otherCore);
		CoreAdminResponse list = req.process(rootServer);
		int state = list.getStatus();
		if (state != 0) {
			throw new SolrServerException("swap失败!");
		}
		
		
	}
	
	
	public static void main(String[] args) {
		
		HttpSolrServer server = new HttpSolrServer("http://localhost:8082/solr");
		/*try {
			swap("newsss","dddsdd",server);
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		*/
		try {
			delCore( "oa_car5", false, server);
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

 

 

© 著作权归作者所有

共有 人打赏支持
hxt168

hxt168

粉丝 8
博文 18
码字总数 16213
作品 3
杭州
程序员
Solr初探(6)——SolrCloud

Solr集群,即是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 。 当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高...

yuanlaijike ⋅ 04/12 ⋅ 0

Solr初探(5)——Solrj的基本使用

导入依赖 导入Solr源码包文件夹下的以及文件夹下的所有包到项目中。除此之外,还要加上包和测试包。 添加/更新数据 Solrj的使用十分简单,下面是一个添加数据的例子: (1)BaseURL就是Solr的...

yuanlaijike ⋅ 04/10 ⋅ 0

Spring Data Lovelace M2 发布,第二个里程碑版本

Spring Data 团队发布了 Lovelace 发行版的第二个里程碑版本。 此版本附带所有包含新功能,改进和错误修复。显着的变化包括: MongoDB 3.6支持更改流和客户端会话(准备MongoDB事务)。 针对...

周其 ⋅ 04/14 ⋅ 0

创建solr7.3.0集群_测试集群_添加中文分词器_导入数据

solr是apache下的一个用于做搜索引擎的高级项目,使用它可以满足绝大部分应用的搜索需求。 主机环境: Linux:centos6.5 JDK:1.8 solr:7.3.0 zookeeper:3.4.8 mmseg4j-solr:2.4.0 1. 创建与启...

特拉仔 ⋅ 04/25 ⋅ 0

Solr4.0的tomcat部署及Solrj的简单使用

Solr简介 Solr是一个非常流行的,高性能的开源企业级搜索引擎平台,属于Apache Lucene项目。主要功能包括强大的全文检索、结果高亮、切面检索、动态聚类、数据库整合、富文本(例如Word,PDF...

beibugulf ⋅ 2016/09/30 ⋅ 0

Solr Apache Solr 初级教程(介绍、安装部署、Java接口、中文分词)

Apache Solr 介绍 Solr 是什么? Solr 是一个开源的企业级搜索服务器,底层使用易于扩展和修改的Java 来实现。服务器通信使用标准的HTTP 和XML,所以如果使用Solr 了解Java 技术会有用却不是...

David_Tio ⋅ 2013/12/05 ⋅ 0

shenzhanwang/Spring-solr

Spring-solr 本项目基于Apache Solr提供一个根据需求配置好的搜索引擎并导入一些初始数据,再基于Spring框架连接solr实现企业级搜索的功能。主要内容如下: 1.搜索引擎基于Solr5.3.1,官网:...

shenzhanwang ⋅ 2016/11/16 ⋅ 0

Apache Solr 之 使用SolrJ操作索引库

Solrj是Solr搜索服务器的一个比较基础的客户端工具,可以非常方便地与Solr搜索服务器进行交互。最基本的功能就是管理Solr索引,包括添加、更新、删除和查询等。对于一些比较基础的应用,用S...

空云万里晴 ⋅ 2014/12/09 ⋅ 1

solr导入pdf操作

索引数据源并不会一定来自于数据库、XML、JSON、CSV这类结构化数据,很多时候也来自于PDF、word、html、word、MP3等这类非结构化数据,从这类非结构化数据创建索引,solr也给我们提供了很好的...

zcl111 ⋅ 2016/07/09 ⋅ 0

Apache solr使用

一、Solr介绍 最近在一个项目中做了一个全文检索的功能,刚开始本来打算用Apache Lucene去实现,毕竟之前对Lucene有一点了解,但是在网上看技术类文章时看见了别人介绍Apache Solr,感觉挺好...

引鸩怼孑 ⋅ 2015/09/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Greys Java在线问题诊断工具

Greys是一个JVM进程执行过程中的异常诊断工具。 在不中断程序执行的情况下轻松完成JVM相关问题排查工作 目标群体 有时候突然一个问题反馈上来,需要入参才能完成定位,但恰恰没有任何日志。回...

素雷 ⋅ 20分钟前 ⋅ 0

git从远程仓库拉取代码的常用指令

一种(比较麻烦的)拉代码的方法 git clone //克隆代码库,与远程代码库的主干建立连接,如果主干已经在就不用再clone啦,克隆路径为当前路径下的新创建的文件夹 git checkout -b //本地建立...

Helios51 ⋅ 34分钟前 ⋅ 0

005. 深入JVM学习—Java堆内存参数调整

1. JVM整体内存调整图解(调优关键) 实际上每一块子内存区域都会存在一部分可变伸缩区域,其基本流程:如果内存空间不足,则在可变的范围之内扩大内存空间,当一段时间之后,内存空间不紧张...

影狼 ⋅ 39分钟前 ⋅ 0

内存障碍: 软件黑客的硬件视图

此文为笔者近日有幸看到的一则关于计算机底层内存障碍的学术论文,并翻译(机译)而来[自认为翻译的还行],若读者想要英文原版的论文话,给我留言,我发给你。 内存障碍: 软件黑客的硬件视图...

Romane ⋅ 今天 ⋅ 0

SpringCloud 微服务 (七) 服务通信 Feign

壹 继续第(六)篇RestTemplate篇 做到现在,本机上已经有注册中心: eureka, 服务:client、order、product 继续在order中实现通信向product服务,使用Feign方式 下面记录学习和遇到的问题 贰 or...

___大侠 ⋅ 今天 ⋅ 0

gitee、github上issue标签方案

目录 [TOC] issue生命周期 st=>start: 开始e=>end: 结束op0=>operation: 新建issueop1=>operation: 评审issueop2=>operation: 任务负责人执行任务cond1=>condition: 是否通过?op3=>o......

lovewinner ⋅ 今天 ⋅ 0

浅谈mysql的索引设计原则以及常见索引的区别

索引定义:是一个单独的,存储在磁盘上的数据库结构,其包含着对数据表里所有记录的引用指针. 数据库索引的设计原则: 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索...

屌丝男神 ⋅ 今天 ⋅ 0

String,StringBuilder,StringBuffer三者的区别

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。 首先说运行速度,或者说是, 1.执行速度 在这方面运行速度快慢为:StringBuilder(线程不安全,可变) > StringBuffer...

时刻在奔跑 ⋅ 今天 ⋅ 0

java以太坊开发 - web3j使用钱包进行转账

首先载入钱包,然后利用账户凭证操作受控交易Transfer进行转账: Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/Credentials credentials = Wallet......

以太坊教程 ⋅ 今天 ⋅ 0

Oracle全文检索配置与实践

Oracle全文检索配置与实践

微小宝 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部