Solr环境搭建及IK分词的集成及solrJ的调用(三)【完结】

前两篇的连接到这里:

Solr环境搭建及IK分词的集成及solrJ的调用(一) http://my.oschina.net/zimingforever/blog/120732

Solr环境搭建及IK分词的集成及solrJ的调用(二) http://my.oschina.net/zimingforever/blog/120928

第一篇讲了如何搭建solr环境,第二篇讲了如何在solr中加入IK的分词。本篇主要介绍如何使用solrJ,solrJ是java客户端调用的api

首先在pom中引入solrJ

<dependency>
   <groupId>org.apache.solr</groupId>
   <artifactId>solr-solrj</artifactId>
   <version>3.6.0</version>
</dependency>
<dependency>
   <groupId>org.apache.solr</groupId>
   <artifactId>solr-core</artifactId>
   <version>3.6.0</version>
</dependency>

接着是solrJ的一些主要用法:

A如何获取一个solrServer并清空里面的索引

public static SolrServer getSolrServer() throws IOException, SolrServerException {
        //连接到solr
        String solrServerUrl = "http://localhost:8084/solr";
        SolrServer solrServer = new CommonsHttpSolrServer(solrServerUrl);
        // 清空之前建立的索引数据 
        solrServer.deleteByQuery("*:*");
        return solrServer;
}
B 建立索引,这里使用的是solrDocument类
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<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
docs.add( doc1 );
docs.add( doc2 );

server.add( docs );
server.commit();
这里建立两个文档,每个文档有3个field,分别是id,name,price,这里要注意一下,这3个filed其实已经在schemal中配置好了,如果你自己定义了filed一定要在schemal.xml中配置好,这也是稍后为什么使用addbean的时候我自定义的field不起作用的原因。

然后把这两个文档放到一个collection中,然后加入到server中,并做一个commit。

这时候solr中就有内容了。可以访问这个地址试试:http://localhost:8084/solr/select/?q=*%3A*&version=2.2&start=0&rows=10&indent=on 会出现索引的内容

Solr环境搭建及IK分词的集成及solrJ的调用(三)【完结】_第1张图片

C 使用addBean增加索引

上面使用的是solrDocument对象增加的索引,其实还有更方便的方法增加索引,方法如下:

Collection<SeacheIndexDO> solrInputDocs = new ArrayList<SeacheIndexDO>();
for(SpiderResultDescribeDO spiderResultDescribeDO:spiderResultDescribeDOs){
   SpiderResultInforDO spiderResultInforDO= (SpiderResultInforDO) sqlMapClient.queryForObject("hunter.getSpinderInfor", spiderResultDescribeDO);
   String fileType=spiderResultInforDO.getUrlKey();
   String fileFullName= AddressUtils.appendUrl(spiderResultInforDO.getBaseUrl(),spiderResultInforDO.getFileName());
   String fileContent=FileUtils.getFileStringByPath(fileFullName, Commons.DEFAULT_DB_CHARSET);
   SeacheIndexDO solrInputDoc=new SeacheIndexDO();
   //id是唯一标示,url是跳转的连接
   solrInputDoc.setId(spiderResultInforDO.getId());
   solrInputDoc.setHunterUrl(spiderResultInforDO.getUrl());
   solrInputDoc.setHunterTitle(spiderResultInforDO.getTitle());
   if(fileType.equals(SpiderSourceType.DBA_WIKI.getStringValue())){
        solrInputDoc.setHunterContent(fileContent);
   }else {
        System.out.println("不支持的类型");
   }
   solrInputDocs.add(solrInputDoc);
}
//增加文档
solrServer.addBeans(solrInputDocs);
// 提交
solrServer.commit();

这里要注意一下,SearchIndexDo是我自定义的类,它里面的属性solr是不认识的,也不知道如何去做索引,所以这个地方必须要把这些属性字段在schemal中做配置

<!--自定义的分词部分-->
<field name="hunterTitle" type="text" indexed="true" stored="true" />
<field name="hunterAuthor" type="string" indexed="true" stored="true" />
<field name="hunterContent" type="text" indexed="true" stored="true" />
<field name="hunterQuestion" type="text" indexed="true" stored="true" />
<field name="hunterAnswers" type="text" indexed="true" stored="true" />
<field name="hunterCreateTime" type="date" indexed="true" stored="true" />
<field name="hunterUpdateTime" type="date" indexed="true" stored="true" />
<field name="hunterUrl" type="string" indexed="true" stored="true" />
<field name="hunterAll" type="text" indexed="true" stored="false" multiValued="true"/>
这里type中的text是我配置好的用IK来分词的filedType,date和string都是默认的类型,另外hunterAll是一个复合字段,再下面有个copyfiled的配置
<!-- 自定义的copyfiled -->
  <copyField source="hunterContent" dest="hunterAll"/>
  <copyField source="hunterTitle" dest="hunterAll"/>
表示把title和content都集合在一起,一起作为搜索的字段。这样之后就可以在搜索的字段中直接搜索hunterAll字段了。


另外还要注意的一点是在bean中对应schemal的字段要加上@Field的注解

D 如何读取solr的data,上面的列子其实就是一个读取*:*的查询

q=*%3A*&version=2.2&start=0&rows=10&indent=on

这里有几个参数q,start,rows,还有几个常用的参数如下:

//        q - 查询字符串,必须的。
//        fl - 指定返回那些字段内容,用逗号或空格分隔多个。
//        start - 返回第一条记录在完整找到结果中的偏移位置,0开始,一般分页用。
//        rows - 指定返回结果最多有多少条记录,配合start来实现分页。
//        sort - 排序,格式:sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]… 。示例:(inStock desc, price asc)表示先 “inStock” 降序, 再 “price” 升序,默认是相关性降序。
//        wt - (writer type)指定输出格式,可以有 xml, json, php, phps, 后面 solr 1.3增加的,要用通知我们,因为默认没有打开。
//        fq - (filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,例如:q=mm&fq=date_time:[20081001 TO 20091031],找关键字mm,并且date_time是20081001到20091031之间的

E 查询的代码如下:

SolrServer server= GetSolrServer.getSolrServer();
SolrQuery query = new SolrQuery();
query.setQuery( "*:*" );
query.addSortField( "price", SolrQuery.ORDER.asc );
QueryResponse rsp = server.query( query );
SolrDocumentList docs = rsp.getResults();
最后一步查询出来的solrDocument,另外也可以使用getBeans方法
List<Item> beans = rsp.getBeans(Item.class);
F 另外在项目中我还用到了高亮查询的结果的方法,这个也是之前在使用luncene没有用到的功能,相关的代码如下:
//设置高亮 给hunterConntent及hunterTitle设置高亮,并设置成红色的格式
        solrQuery.setHighlight(true);
        solrQuery.addHighlightField("hunterTitle");
        solrQuery.addHighlightField("hunterContent");
        solrQuery.setHighlightSimplePre("<font color=\"red\">");
        solrQuery.setHighlightSimplePost("</font>");
表示给其中的title和content设置高亮,高亮的格式是使用红色的font

获取高亮的代码如下,它和获取查询结果返回的对象不是一个,还要分别处理,代码上也有些“不干净”

Map<String, Map<String, List<String>>> queryResponseHighlighting =queryResponse.getHighlighting();

G 另外之前提到了在自定义的field中我做了一个hunterAll字段

//设置查询的范围
        solrQuery.set("df",queryFiled);
        //设置查询的字
        solrQuery.setQuery(queryText);
那么在查询的时候我就不用使用类似于*:*的格式了,而表示直接在hunterAll这个字段中去取queryText

H 另外返回查询的状态和时间如下:

//获取status
        int responseStauts=queryResponse.getStatus();
        //获取responseTime
        int responseTime=queryResponse.getQTime();

总结一下:本篇博客主要介绍了solrj的常用使用方法,我基本上使用上面的代码接完成了建立索引和查询。另外结合前两篇的博客基本上可以使用简单的solr了。


你可能感兴趣的:(Solr环境搭建及IK分词的集成及solrJ的调用(三)【完结】)