SolrJ

来源:互联网 发布:mac pretty boy 编辑:程序博客网 时间:2024/05/21 18:41

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");

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);  

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);  

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

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

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

4 结果集获取

QueryResponse response = server.query(query);   SolrDocumentList results = response.getResults();

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

for(SolrDocument doc:results){      //....                              }

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);

完整示例:

/** * 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();        }    }
1 0