Solr

Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。

 
中文名企业级搜索应用服务器
外文名 Solr
功    能  提供API接口

特点

编辑
Solr是一个高性能,采用Java5开发,
SolrSolr
基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎
 
 
 

工作方式

编辑
文档通过Http利用XML 加到一个搜索集合中。
SolrSolr
查询该集合也是通过http收到一个XML/JSON响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。[1] 
 
 
 

1、  创建solrserver对象:

try {

               solr = new CommonsHttpSolrServer("http://localhost:8983/solr");

               solr.setConnectionTimeout(100);

               solr.setDefaultMaxConnectionsPerHost(100);

               solr.setMaxTotalConnections(100);

        } catch (Exception e) {

               System.out.println("请检查tomcat服务器或端口是否开启!");

               e.printStackTrace();

        }

 

2、  添加索引

Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();

        for (int i = 0; i < list.size(); i++) {

               Item item = list.get(i);

               //设置每个字段不得为空,可以在提交索引前进行检查

               if (CheckItem(item)) {

                      SolrInputDocument doc = new SolrInputDocument();

                      //在这里请注意date的格式,要进行适当的转化,上文已提到

                      doc.addField("id", item.getId());

                      …………

                      docs.add(doc);

               }

        }

 

        try {

               solr.add(docs);

               //对索引进行优化

               solr.optimize();

               solr.commit();

        } catch (Exception e) {

               e.printStackTrace();

        }

3、  使用bean对象添加索引

       创建一个对应于solr索引的类别:

       public class Item {

              @Field

              private String id;

              …………

              public void setId(String id) {

                     this.id = id;

              }

              public String getId() {

                     return id;

              }

              …………

              public Item(){

              }

       }

 

       使用数据创建bean对象列表,

        try {

              solr.addBeans(beansList);

              } catch (Exception e) {

                     e.printStackTrace();

              } finally {

                     try {

                            solr.optimize();

                            solr.commit();

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

              }

       索引提交完毕。

 

4、  删除索引

       据查询结果删除:      

        try {

                     //删除所有的索引

                     solr.deleteByQuery("*:*");

                     solr.commit();

              } catch (Exception e) {

                     e.printStackTrace();

              }

 

       根据索引号删除索引:

       try {

                     solr.deleteById(ids);

                     solr.commit();

              } catch (Exception e) {

                     e.printStackTrace();

              }

 

5、  查询

       SolrJ提供的查询功能比较强大,可以进行结果中查询、范围查询、排序等。

       下面是笔者封装的一个查询函数:

      

       public static QueryResponse Search(String[] field, String[] key, int start,

                     int count, String[] sortfield, Boolean[] flag, Boolean hightlight) {

              //检测输入是否合法

              if (null == field || null == key || field.length != key.length) {

                     return null;

              }

              if (null == sortfield || null == flag || sortfield.length != flag.length) {

                     return null;

              }

             

              SolrQuery query = null;

              try {

                     //初始化查询对象

                     query = new SolrQuery(field[0] + ":" + key[0]);

                     for (int i = 0; i < field.length; i++) {

                            query.addFilterQuery(field[i] + ":" + key[i]);

                     }

                     //设置起始位置与返回结果数

                     query.setStart(start);

                     query.setRows(count);

                     //设置排序

                     for(int i=0; i<sortfield.length; i++){

                            if (flag[i]) {

                                   query.addSortField(sortfield[i], SolrQuery.ORDER.asc);

                            } else {

                                   query.addSortField(sortfield[i], SolrQuery.ORDER.desc);

                            }

                     }

                     //设置高亮

                     if (null != hightlight) {

                            query.setHighlight(true); // 开启高亮组件

                            query.addHighlightField("title");// 高亮字段

                            query.setHighlightSimplePre("<font color="red">");// 标记

                            query.setHighlightSimplePost("</font>");

                            query.setHighlightSnippets(1);//结果分片数,默认为1

                            query.setHighlightFragsize(1000);//每个分片的最大长度,默认为100

                     }

              } catch (Exception e) {

                     e.printStackTrace();

              }

 

              QueryResponse rsp = null;

              try {

                     rsp = solr.query(query);

              } catch (Exception e) {

                     e.printStackTrace();

                     return null;

              }

              //返回查询结果

              return rsp;

       }

       补充一下范围查询的格式:[star t TO end],start与end是相应数据格式的值的字符串形式,“TO”     一定要保持大写!

 

6、  读取查询结果

       DocList读取返回结果:

       SolrDocumentList solrList = rsp.getResults();

 

       Beans读取返回结果:

       List<Item> tmpLists = rsp.getBeans(Item.class);

 

       读取高亮显示结果:

                     rsp = Search(field, key, 0, 10, sortfield, flag, true);

                     if(null == rsp){

                            return;

                     }

                     Map<String, Map<String, List<String>>> hightlight = rsp.getHighlighting();

                     //Item即为上面定义的bean类

                     List<Item> tmpLists = rsp.getBeans(Item.class);

                     for (int i = 0; i < tmpLists.size(); i++) {

                            //hightlight的键为Item的id,值唯一,我们设置的高亮字段为title

                            String hlString = hightlight.get(tmpLists.get(i).getId()).get("title").toString();

                            if (null != hlString) {

                                   System.out.println(hlString);

                            }

                     }

 

7、  Facet的一个应用:自动补全

       //prefix为前缀,min为最大返回结果数

       public static String[] autoComplete(String prefix, int min) {

              String words[] = null;

              StringBuffer sb = new StringBuffer("");

              SolrQuery query = new SolrQuery("*.*");

              QueryResponse rsp= new QueryResponse();

              //Facet为solr中的层次分类查询

              try {

                     query.setFacet(true);

                     query.setQuery("*:*");

                     query.setFacetPrefix(prefix);

                     query.addFacetField("title");

                     rsp = solr.query(query);

              } catch (Exception e) {

                     // TODO: handle exception

                     e.printStackTrace();

                     return null;

              }

             

              if(null != rsp){

                     FacetField ff = rsp.getFacetField("title");

                     List<Count> countList = ff.getValues();

                     if(null == countList){

                            return null;

                     }

                     for(int i=0; i<countList.size(); i++){

                            String tmp[] = countList.get(i).toString().split(" ");

                            //排除单个字

                            if(tmp[0].length()< 2){

                                   continue;

                            }

                            sb.append(tmp[0] + " ");

                            min--;

                            if(min == 0){

                                   break;

                            }

                     }

                     words = sb.toString().split(" ");

              }else{

                     return null;

              }

              return words;

       }

 

 
 
posted @ 2016-12-20 08:56  小皇帝POP  阅读(166)  评论(0编辑  收藏  举报