设为首页 收藏本站
查看: 1198|回复: 0

[经验分享] 使用solrj操作solr索引库,solr是lucene服务器

[复制链接]
累计签到:19 天
连续签到:1 天
发表于 2015-7-17 13:35:28 | 显示全部楼层 |阅读模式
客户端开发 Solrj


  客户端开发 Solrj
  Solr是搭建好的lucene服务器 当然不可能完全满足一般的业务需求 可能 要针对各种的架构和业务调整 这里就需要用到Solrj了
  Solrj是Solr提供的api库 可以进行Solr 的二次开发。
  主要实现原理 服务端利用httpClient发送Solr格式的HTTP请求 到Solr服务器  然后服务器根据请求去找索引( 当然你要先针对数据源创建索引)最后返回SolrDocument. 然后你再进一步处理 高亮 排序 等功能。
   1. 创建连接
   HttpSolrServer solrServer  = SolrServiceConfiger.getInstance().getServer();
  //这里创建的一个HTTP请求 用的4.1的JAR Solr3.6之前用的CommonHttpSolrServer.新版改成这个类了 创建一个单例服务。
   2. 创建索引
  /***
  * 创建Solr索引 通过指定的实体
  */
  public void create(T t) {
  SolrEntityBinder binder = new SolrEntityBinder();//这里这个类是源码DocumentObjectBinder处理类 这里为了实体转换改写了里面一些判断后面会讲到 剩下没改过
  SolrInputDocument doc = binder.toSolrInputDocument(t); //把你的实体对象转换成Solr输入文档对象
  try {
  solrServer.add(doc);//添加文档
  solrServer.commit();//提交请求
  } catch (SolrServerException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
    3 .删除索引
  /**
  * 删除指定ID的索引
  */
  public void delete(PK id) {
  try {
  solrServer.deleteById((String)id );//直接根据ID删除 solrServer.deleteByQuery("*:*");删除所有   
  solrServer.commit();
  } catch (SolrServerException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
    4.修改索引
     直接先删除后创建
    5.查询索引
    public Page luceneSearch(String content,Page page) {
  String id = null;
  try {
  HttpSolrServer server = SolrServiceConfiger.getInstance().getServer();// 创建服务 */
  SolrQuery sQuery = new SolrQuery();  // 创建solr查询对象
  String para="";  
  if(StringUtils.isNotEmpty(content)){ // 拼接solr查询条件
  para ="company:"+content;
  }
  if(!StringUtils.isNotEmpty(para)){  
  para="*:*";   
  }
  sQuery.setQuery(para)
  .setStart((page.getPageNo()-1)*page.getPageSize())
  .setRows(page.getPageSize());  
  //设置高亮  
  sQuery.setHighlight(true); // 开启高亮组件  
  sQuery.addHighlightField("company");// 高亮字段  
  sQuery.setHighlightSimplePre("");//标记,高亮关键字前缀  
  sQuery.setHighlightSimplePost("");//后缀  
  sQuery.setHighlightSnippets(2);//结果分片数,默认为1  
  sQuery.setHighlightFragsize(1000);//每个分片的最大长度,默认为100  
  sQuery.setFacet(true).setFacetMinCount(1)
  .setFacetLimit(5)//段  
  .addFacetField("company");//分片字段  
  //返回结果
  QueryResponse response = server.query(sQuery);  
  //得到文档列表
  SolrDocumentList list = response.getResults();  
  //得到总数 设置
  Integer counts=(int) list.getNumFound();               
  page.setTotalCount(counts);
  //得到高亮数据
  Map highlightMap=response.getHighlighting(); //得到高亮集合
  //创建对象转换对象
  DocumentObjectBinder binder = new DocumentObjectBinder();  
  //转换对象
  List demoList= binder.getBeans(Demo.class, list);
  //设置高亮结果
  for(Demo d :demoList){
  id = d.getId();
  List companyList = highlightMap.get(id).get("company");         
  if(companyList!=null&&companyList.size()>0){
  d.setCompany(companyList.get(0));
  }        
  }
  //返回结果
  page.setResult(demoList);
  
  } catch (Exception e) {
  e.printStackTrace();
  }  
  return page;
  }  
  常见问题
  1. org.apache.solr.client.solrj.SolrServerException:
  Timeout occured while waiting response from server at: http://localhost/solr请求超时
  解决方法:设置setConnectionTimeout和setSoTimeout为1分钟
  2. org.apache.solr.common.SolrException: undefined field text
  解决方法: 设置solrConfig.xml id 默认是text
  3. org.apache.solr.common.SolrException: Invalid Date String时间格式化问题
  主要是Solr使用的是标准的格林威治(GMT)时间 这种(yyyy-MM-dd'T'HH:mm:ss.SSS'Z')北京在东八区 默认时间会-8小时
  所以为了满足他这个减8 我的做法是在创建索引格式化日期类型的时候 判断下 把它时间+8 。
  所以重新创建一个SolrEntityBinder类 此类是完全copy的DocumentObjectBinder. 只修改了一处。
  修改了类中toSolrInputDocument方法
  //判断是否是日期-------------///
  if(field.type==Date.class){
  Date d = (Date)field.get(obj);
  Calendar cal = Calendar.getInstance();
  cal.setTimeInMillis(d.getTime());
  cal.add(Calendar.HOUR, 8);
  d = cal.getTime();
  doc.setField(field.name,d,1.0f);
  }else{
  doc.setField(field.name, field.get(obj), 1.0f);
  }
  --------------------------------------------
  (solrj)初次使用solr的开发人员总是很郁闷,不知道如何去操作solr索引库,以为只能用《五分钟solr4.5教程(搭建、运行)》中讲到的用xml文件的形式提交数据到索引库,其实没有那么麻烦,solr配套有好多的客户端用于操作索引库,下面我们来讲如何用solrj去操作solr索引库。
  一、认识solrj
  solrj是solr的java客户端,用于访问solr索引库。它提供了添加、删除、查询、优化等功能。
  
  二、下载
  百度、google以下solrj下载,你会发现根本就没有,那么我们该到哪儿下载呢?其实,它是集成到solr压缩包里的,解压文件后,有个目录/dist/solrj-lib,里面就存放了solrj所用到的jar,你把这些jar都添加到你的classpath就ok。
  如果你是使用Maven来构建项目,添加以下代码到你的pom.xml配置文件中:


        solr-solrj
        org.apache.solr
        1.4.0
        jar
        compile


        org.slf4j
        slf4j-simple
        1.5.6

  
  三、创建SolrServer
  1、HttpSolrServer
  solrj是采用http请求的方式去访问solr索引库的,首先我们得先创建一个HttpSolrServer,如下:

String url = "http://localhost:8983/solr";//8983是web服务器的端口号,需要根据情况进行调整
SolrServer server = new HttpSolrServer( url );
  以上使用默认的方式创建server,你也可以配置其他的连接参数:

String url = "http://localhost:8983/solr" ;
HttpSolrServer server = new HttpSolrServer( url ); server.setMaxRetries(1); // defaults to 0. > 1 not recommended. server.setConnectionTimeout(5000); // 5 seconds to establish TCP
// Setting the XML response parser is only required for cross
// version compatibility and only when one side is 1.4.1 or
// earlier and the other side is 3.1 or later. server.setParser(new XMLResponseParser());
// binary parser is used by default
// The following settings are provided here for completeness.
// They will not normally be required, and should only be used
// after consulting javadocs to know whether they are truly required.
server.setSoTimeout(1000); // socket read timeout
server.setDefaultMaxConnectionsPerHost(100);
server.setMaxTotalConnections(100);
server.setFollowRedirects(false); // defaults to false
// allowCompression defaults to false.
// Server side must support gzip or deflate for this to have any effect.
server.setAllowCompression(true);
  2、EmbeddedSolrServer
  EmbeddedSolrServer提供了和HttpSolrServer一样的接口,区别是EmbeddedSolrServer没有通过http连接。

//Note that the following property could be set through JVM level arguments too
System.setProperty("solr.solr.home", "d:/solr_home/solr"); //此处配置solr home,根据自己的情况修改
CoreContainer.Initializer initializer = new CoreContainer.Initializer();
CoreContainer coreContainer = initializer.initialize();
EmbeddedSolrServer server = new EmbeddedSolrServer(coreContainer, "");
  当然实际中可能不止一个core,那么采用如下方式:

File home = new File( "d:/solr_home/solr" );//此处配置solr home,根据自己的情况修改
File f = new File( home, "solr.xml" );
CoreContainer container = new CoreContainer();
container.load( "d:/solr_home/solr", f );

   
EmbeddedSolrServer server = new EmbeddedSolrServer( container, "core name as defined in solr.xml" );//双引号配置你的core名字
...
  在嵌入式的应用中使用solr,推荐使用EmbeddedSolrServer。
  注意:EmbeddedSolrServer使用有个前提条件,需要在solrconfig.xml配置相对应的RequestHandler,如:/update对应更新操作。
  
  四:solrj的使用
  创建好server以后,我们就可以开始solrj操作索引库了!!
  首先创建一个server,最好的方式是采用单例模式,不要重复去创建。

SolrServer server = new HttpSolrServer("http://HOST:8983/solr/");
  1、添加文档到索引库
  //创建一个文档

SolrInputDocument doc1 = new SolrInputDocument();
doc1.addField( "id", "id1", 1.0f );
doc1.addField( "name", "doc1", 1.0f );
doc1.addField( "price", 10 );
  //再创建一个文档

SolrInputDocument doc2 = new SolrInputDocument();
doc2.addField( "id", "id2", 1.0f );
doc2.addField( "name", "doc2", 1.0f );
doc2.addField( "price", 20 );
  //创建一个collection,把以上两个文档添加进去

Collection docs = new ArrayList();
docs.add( doc1 );
docs.add( doc2 );
  //把文档添加到server中

server.add( docs );
  //提交文档

server.commit();//此处只是提交到索引中,不会出现在搜索结果中;如果想立马搜索,请使用commit(boolean waitFlush, boolean waitSearcher)方法
  如果你想添加到server后想快速提交(commit),可以采用如下方式:

UpdateRequest req = new UpdateRequest();
req.setAction( UpdateRequest.ACTION.COMMIT, false, false );
req.add( docs );
UpdateResponse rsp = req.process( server );
  2、添加pojo到索引库
  除了通过文档的形式提交以外,solrj还可以通过pojo的方式提交。使用注解@Field映射到schema.xml中定义的字段中
  创建一个javaBean:

import org.apache.solr.client.solrj.beans.Field;
public class Item {
@Field
String id;
@Field("cat")//自定义字段名
String[] categories;
@Field
List features;
public void setId(String id) {
this.id = id;
}
public void getId() {
return this.id;
}
//其他get、set方法
}
  创建JavaBean的实例:

Item item = new Item();
item.id = "one";
item.categories = new String[] { "aaa", "bbb", "ccc" };
  添加到server中:

server.addBean(item);
  提交到索引:

server.commit();
  还可以同时添加多个javaBean:

List beans ;
//add Item objects to the list  
server.addBeans(beans);
  3、删除索引

server.deleteById(String id);
或者
deleteById(List ids);
  4、更新索引
  solr索引库不同于数据库,没有更新的功能。如果想更新,先通过id删除对应的文档,再天新的文档。
  5、查询索引

SolrQuery query = new SolrQuery();
query.setQuery( "*:*" );
query.addSortField( "price", SolrQuery.ORDER.asc );
QueryResponse rsp = server.query( query );
  //文档方式读取

SolrDocumentList docs = rsp.getResults();//实际项目中如果业务比较复杂,采用这种方式显得比较灵活
  //使用javaBean的方式读取

List beans = rsp.getBeans(Item.class);
  6、高级使用

SolrServer server = getSolrServer();
SolrQuery solrQuery = new SolrQuery()
                      . setQuery("ipod")
. setFacet(true)
. setFacetMinCount(1)
. setFacetLimit(8)
. addFacetField("category")
. addFacetField("inStock");
QueryResponse rsp = server.query(solrQuery);
  7、高亮显示

SolrQuery query = new SolrQuery(); query.setQuery("foo");
query.setHighlight(true).setHighlightSnippets(1);
//set other params as needed
query.setParam("hl.fl", "content");
QueryResponse queryResponse = getSolrServer().query(query);
  处理高亮显示结果:

Iterator iter = queryResponse.getResults().iterator();
while (iter.hasNext()) {
SolrDocument resultDoc = iter.next();
String content = (String) resultDoc.getFieldValue("content");
String id = (String) resultDoc.getFieldValue("id"); //id is the uniqueKey field
if (queryResponse.getHighlighting().get(id) != null) {
List highlightSnippets = queryResponse.getHighlighting().get(id).get("content");
}
}

  本文出自 luoshengsha.com,转载时请注明出处及相应链接。
  本文永久链接: http://www.luoshengsha.com/245.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-87711-1-1.html 上篇帖子: Solr部署到web项目中 下篇帖子: Solr 4.0: Partial documents update
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表