SolrJ

版权声明:博主地址:http://blog.csdn.net/zcl_love_wx https://blog.csdn.net/zcl_love_wx/article/details/52302658

SolrJ是Solr的客户端,简化开发量

这里需要jar包有:
solr-core-5.3.1.jar
solr-solrj-5.3.1.jar

SolrJ使用步骤

1 建立与Solr服务的连接

 HttpSolrClient server = new HttpSolrClient("http://localhost:8080/solr/ims_advertiser_core");
 
 
  • 1

2 配置参数

server.setSoTimeout(3000); // socket read timeout  
server.setConnectionTimeout(1000);  
server.setDefaultMaxConnectionsPerHost(1000);  
server.setMaxTotalConnections(10);  
server.setFollowRedirects(false); // defaults to false  
server.setAllowCompression(true); // 允许压缩,减少数据量
server.setMaxRetries(1);  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3 填充搜索条件(以SolrQuery对象 )

下面填充相当于拼接的http请求:
http://localhost:8989/solr/select?q=tags:t5 AND t7&fl=auction_id&start=0&rows=4&sort=auction_id desc,auction_point asc 这个链接。

SolrQuery query = new SolrQuery();

query.setQuery("tags:t5 AND t7");  
query.addField("auction_id");  
query.setStart(0);  
query.setRows(4);  
query.addSortField("auction_id", SolrQuery.ORDER.desc);  
query.addSortField("auction_point", SolrQuery.ORDER.asc);  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

通过query对象填充搜索条件时,还可以键值对的形式填充,如:

query.set("start", 0);              //从第条数据开始
query.set("rows",4);                //共返回多少条数据          
query.set("sort", "auction_idasc"); //按id升序排列。desc降序
 
 
  • 1
  • 2
  • 3

后面我会在示例代码中写出另一种以Map方式填充搜索条件的方式,当然结果集的获取也会不一样

4 结果集获取

QueryResponse response = server.query(query);   

SolrDocumentList results = response.getResults();
 
 
  • 1
  • 2
  • 3

QueryResponse这个对象,是对Response的一次封装。而response.getResults()获得的对象正是SolrJ帮我们做的最关键的操作。最终我们获得的对象SolrDocumentList,非常类似我们在jdbc里的ResultSet,得到结果后,只需一个遍历就行:

for(SolrDocument doc:results){  
    //....                              
}
 
 
  • 1
  • 2
  • 3

SolrJ与拼接链接方式的区别

1 请求方面

不用SolrJ :

如果采用http直接访问的方法,我们必然会用到httpclient请求Solr服务器。其中所有的搜索条件都必须通过拼接一个负责冗长的url,例如:q=tags:t5 AND t7&fl=auction_id&start=0&rows=4&sort=auction_id desc&…&…&… ,通过GET的方式,请求服务器。

用SolrJ :

面对对象的思想,所有搜索条件均以setter属性的方式设置到其封装的对象当中。但是,实际上还是通过拼接url的方式,走http请求的方式再请求Solr服务器。

所以,有了Solrj,开发会省很多事,将很多开发中的体力活交给Solrj。但是直接拼接url的方式肯定比对象的方式灵活很多。因为不复杂,有兴趣的同学,可以给Solrj加个方法,直接在Solrj最终生成的url上加上任何字符串。

2 获取结果方面

不用SolrJ:

结果的返回形式是xml文件,每条记录都会以document节点的形式记录。如果要获得Object对象,我们一般会用Dom4j或者xStream等技术对结果的xml进行解析。

用SolrJ:

直接获得结果,无需解析xml。优点显而易见!

示例代码

当以Map方式 (这里的Map对象是paramMaps) 填充搜索条件时,需要用SolrParams 对象来获取QueryResponse

SolrParams params = new MapSolrParams(paramMaps);
QueryResponse resp = server.query(params);
 
 
  • 1
  • 2

完整示例:

/**
 * SolrJ的增删改查
 * @author 张春玲
 *  SolrJ是访问Solr 的Java客户端框架。使用SolrJ的前提是在tomcat里配置好了solr,并且将数据库数据导入到了solr_home里的core里
 *  需将noggit-0.5.jar包 加入工程,防止下面的异常:
 *  Exception in thread "main" java.lang.NoClassDefFoundError: org/noggit/CharArr
 */
public class SolrJUtil {

    /**
     * Solr服务器路径
     * http://localhost:8080/solr这部分直接在浏览器访问时,会出现solr管理界面
     * ims_advertiser_core是solr_home里的core
     */
    public static final String SOLR_URL="http://localhost:8080/solr/ims_advertiser_core";


    /**
     * Solr服务器客户端,因此说SolrJ是访问Solr 的Java客户端框架。来源solr-solrj-5.3.1.jar。HttpSolrServer过时了
     */
    private  HttpSolrClient server;

    /**
     * 构造方法
     */
    public SolrJUtil(){
        server = new HttpSolrClient(SOLR_URL);//根据solr路径连接solr服务器
        server.setAllowCompression(true);//允许压缩,减少数据量
    }


    /**
     * 查询:返回SolrJ查询Solr服务器的数据。 《已测试》----------------------------------------
     * SolrJ的查询与在solr管理界面的查询是一样的,只是管理界面将所有字段做成了表格的形式,我们只需填值就行了,
     * 而SolrJ不仅需要填值,还需要填对应的字段。SolrJ能查询的前提solr服务器已经将数据库的数据导入了。
     * 一般开发都只用查询功能的,索引的更新基本上都是使用 crond。
     * 
     * 高亮的前提是,core里schema.xml文件配置高亮字段时,需将该field的type属性改为分词器,如中文分词type="text_ik",且stored="true"。
     * 
     * @param keyword 它是搜索时的关键字
     * @return
     */
    public List<String> search(String keyword){
        List<String> autoList=new ArrayList<String>();

        if (keyword== null || keyword.trim().length()==0) {
            return autoList;
        }

        SolrQuery query = new SolrQuery();
        QueryResponse response = null;

        try {           
            //query.set("q","*:*");                 //q表示查询关键词,*:*代表查询所有属性、所有值,即所有索引(index)
            query.set("q", "keyword:"+keyword);     //表示查询关键字里包含keyword的所有结果,这儿keyword为“东”
            query.set("start", 0);                  //从第条数据开始
            query.set("rows",5);                    //共返回多少条数据          
            query.set("sort", "advertiserId asc");  //按id升序排列。desc降序
            query.set("spellcheck.build", "true");  //拼音检查

            /* 设置高亮。
             * 高亮的前提是,在core里schema.xml文件配置高亮字段时,需将该field的type属性改为分词器,如中文分词type="text_ik",且stored="true"。
             */
            query.set("hl", "true");                        // 开启高亮组件  
            query.set("spellcheck.build", "true");          //拼音检查
            query.set("hl.fl","shortName,companyName");     // 高亮字段  
            query.set("hl.simple.pre","<font color='red'>");//高亮样式标签(开始标签):颜色
            query.set("hl.simple.post", "</font>");         //高亮样式标签(结束标签)

            response = server.query(query);                 //放进solr服务器,连接后返回相应数据

            /* results是查回的多个javabean对象拼成的json串,格式如下:
             * {numFound=35,start=0,docs=[
             *  SolrDocument{advertiserType=52, id=300, userName=135@qq.com, shortName=东方, disabled=2, advertiserId=82, _version_=1527113164097847296},
             *  SolrDocument{advertiserType=51, id=302, userName=1351@qq.com, shortName=东看, disabled=2, advertiserId=83, _version_=1527113164095750144}, 
             *  SolrDocument{advertiserType=51, id=306, userName=135@qq.com, shortName=东要, disabled=2, advertiserId=85, _version_=1527113164105187328}, 
             *  SolrDocument{advertiserType=51, id=308, userName=135@qq.com, shortName=工工, disabled=2, advertiserId=86, _version_=1527113164106235904}, 
             *  SolrDocument{advertiserType=52, id=310, userName=135@qq.com, shortName=东方不, disabled=2, advertiserId=87, _version_=1527113164107284480}
             * ]}
             *  
             */
            SolrDocumentList results = response.getResults();
            System.out.println("查回的多个结果对象:"+results);

            /* 高亮结果格式如下:
             * {82={}, 83={shortName=[<font color='red'>东</font>看]}, 86={}, 87={}, 85={shortName=[<font color='red'>东</font>要]}}
             * 可以看到,高亮结果是以advertiserId为键,以字段对应的结果为值的键值对,所以要想取到具体某个高亮结果,还需从results里先得到advertiserId,然后通过该ID去高亮结果取值。
             * 高亮结果之所以能高亮,是因为在查回的结果里将关键字用样式包围了,如shortName=[<font color='red'>东</font>看]},这个样式能直接返回到页面。
            */
            Map<String, Map<String, List<String>>> highLightResultMap = response.getHighlighting();
            System.out.println("高亮结果:"+highLightResultMap);


            for(SolrDocument doc:results){
                //doc格式:SolrDocument{advertiserType=51, id=302, userName=1351@qq.com, shortName=东看, disabled=2, advertiserId=83, _version_=1527113164095750144}
                if(highLightResultMap!=null){                   
                    Object advertiserId =  doc.getFieldValue("advertiserId");//得到ID
                    Map<String, List<String>> map = highLightResultMap.get(advertiserId.toString());//通过ID去取结果
                    System.out.println("map:"+map);
                    if(map!=null){
                        //map格式:{shortName=[<font color='red'>东</font>要]}
                        List<String> list = map.get("shortName");
                        //list格式: [<font color='red'>东</font>看]
                        //System.out.println(list);

                        //获取高亮的单个结果,是先从单个查回结果里取到advertiserId的值,然后通过该值去高亮结果里取值
                        //List<String> highLightSnippets = highLightResultMap.get(doc.getFieldValue("advertiserId")).get("shortName");
                        if(list!=null&&list.size()>0){
                             for(int i =0 ; i < list.size() ;i++){  
                                    String temp = list.get(i);  
                                   // System.out.println("title高亮返回为:  "  + temp);  
                                    autoList.add(temp);
                             }  
                        }
                    }                   
                }                               
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return autoList;
    }

    /**
     * 查询:SolrJ查询Solr服务器数据   [map封装参数方式]    -----------------------------------
     * 
     */
    public List<UserAdvertiser> search(String keyword, short advertiserType, short disabled, int pageNo, int pageSize)
            throws Exception {
        Map<String, String> maps = new HashMap<String, String>();


        if(StringUtils.isEmpty(keyword)){
            maps.put("q", "*:*");
        }else{
            maps.put("q", "keyword:" + keyword);
        }

        String qurey="";
        if(advertiserType>0){
            qurey="advertiserType:" + advertiserType;
            if(disabled>0){
                qurey=qurey + " AND disabled:" + disabled;
            }
        }else{
            if(disabled>0){
                qurey="disabled:" + disabled;
            }
        }
        maps.put("fq",qurey);
        maps.put("start", String.valueOf(pageNo));
        maps.put("rows", String.valueOf(pageSize));
        maps.put("sort", "advertiserId desc");//走索引时 按id排序

        //设置高亮
        maps.put("hl","true");
        maps.put("hl.fl", "shortName");
        maps.put("hl.simple.pre","<font color='red'>");
        maps.put("hl.simple.post", "</font>");

        SolrParams params = new MapSolrParams(maps);
        QueryResponse resp = server.query(params);//添加进服务器

        SolrDocumentList docsList=resp.getResults();                                 //得到匹配结果
        Map<String, Map<String, List<String>>> highlighting = resp.getHighlighting();//得到高亮结果
        if (docsList == null || docsList.size() == 0) {
            return null;
        }

        List<UserAdvertiser> advList = new ArrayList<UserAdvertiser>();
        UserAdvertiser vo = null;
        for (SolrDocument doc : docsList) {
            int advertiserId=Integer.parseInt(String.valueOf(doc.get("advertiserId")));
            vo = new UserAdvertiser();
            vo.setId(Integer.parseInt(String.valueOf(doc.get("id"))));
            vo.setAdvertiserId(advertiserId);
            vo.setAdvertiserType(Short.parseShort(String.valueOf(doc.get("advertiserType"))));
            vo.setDisabled(Short.parseShort(String.valueOf(doc.get("disabled"))));
            /*vo.setShortName(String.valueOf(doc.get("shortName")));//shortName字段要替换成高亮结果*/
            vo.setUserName(String.valueOf(doc.get("userName")));
            /*ListStat listStat=listStatDao.getCampaignCount(advertiserId);
            if(listStat!=null){
                vo.setCampaignNum(listStat.getCount());
            }*/
            Map<String, List<String>> map = highlighting.get(doc.get("advertiserId").toString());//得到ID
            List<String> list_l = map.get("shortName");//通过ID去查回高亮结果
            if(list_l!=null && list_l.get(0)!=null){
                vo.setShortName(list_l.get(0));
            }else{
                //如果高亮结果为空,则用前面查回的匹配结果。
                vo.setShortName(String.valueOf(doc.get("shortName")));
            }
            if(String.valueOf(doc.get("shortName")).trim().indexOf("[")!=-1
                    &&String.valueOf(doc.get("shortName")).trim().indexOf("]")!=-1) {//去中括号
                String shortName = String.valueOf(doc.get("shortName")).trim();
                vo.setShortName(shortName.substring(1,shortName.length()-1));
            }
            advList.add(vo);//将对象添加进list结果
        }

        return advList;

    }

    /**
     * 添加
     * @param advertiser
     */
    public void add(UserAdvertiser advertiser){
        SolrInputDocument doc = new SolrInputDocument();
        doc.addField("advertiserId", advertiser.getAdvertiserId());
        doc.addField("shortName", advertiser.getShortName());
        try {
            server.add(doc);
            server.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 更新
     */
    public void update(UserAdvertiser advertiser){
        add(advertiser);//添加就是更新
    }

    /**
     * 删除
     */
    public void delete(){
        try {
            server.deleteByQuery("*:*");//删除所有
            server.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值