利用SOLR搭建企业搜索平台 之五(solrj)

随手一记 2012-03-27

利用SOLR搭建企业搜索平台 之五(solrj)

博客分类: solr
Solr企业应用QtApache编程
http://www.dzxiaoshuo.com 

相信很多人,在准备提交数据让solr建立索引的那刻,很纳闷,尽管看了不少网上的一些文章,但是我想依然还是有不少不理解的地方。

比如提交一个xml,采用post方式,尽管有些文章说了可以采用httpclient。但是我那个时候,还不是很理解,当然现在看来其实也没有什么了。但是对于一个刚入门solr的初学者,我想讲讲关于solr1.3的solrj(sorlrJ目前使用二进制的格式作为默认的格式。对于solr1.2的用户通过显示的设置才能使用XML格式。)!

先上一个例子:

public static final String SOLR_URL = "http://localhost/solr/core0";  
public static void commit() {  
    Date date = new Date();  
    SolrServer solr = null;  
    try {  
        solr = new CommonsHttpSolrServer(SOLR_URL);  
    } catch (MalformedURLException e1) {  
        e1.printStackTrace();  
    }  
for (int i = 0; i < 10000; i++) {  
            SolrInputDocument sid = new SolrInputDocument();  
            sid.addField("id", i);  
            sid.addField("name", "struts+hibernate+spring 开发大全" + i);  
            sid.addField("summary", "三种框架的综合应用" + i);  
            sid.addField("author", "李良杰" + i);  
            sid.addField("date", new Date());  
            sid.addField("content", "高级应用类书籍" + i);  
            sid.addField("keywords", "SSH" + i);  
            try {  
                solr.add(sid);  
            } catch (MalformedURLException e) {  
                e.printStackTrace();  
            } catch (SolrServerException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            System.out.println(i);  
            if (i == 999)   
                System.out.println((new Date().getTime() - date.getTime()) / 60000 + "分钟");  
        }  
        try {  
            solr.commit();  
        } catch (SolrServerException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
}  

上面这段代码的意思是:利用for提交10000个document,并打印提交10000所需的时间。

1》CommonsHttpSolrServer使用HTTPClient和solr服务器进行通信。

2》CommonsHttpSorlrServer允许设置链接属性。

server.setSoTimeout(1000);  // socket read timeout    
  server.setConnectionTimeout(100);    
  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);    
  server.setMaxRetries(1); // defaults to 0.  > 1 not recommended.  
  

3》实现SolrServer接口的另一个类:EmbeddedSorrServer,它不需要http连接。

4》在构造document的时候,可以一个一个添加到solrServer,也可以构建一个包含document的Collection,将Collection添加到solrServer,然后commit。

5》也可以构造一个跟document匹配的JavaBean进行提交

使用java注释创建javabean。@Field,可以被用在域上,或者是setter方法上。如果一个域的名称跟bean的名称是不一样的,那么在java注释中填写别名,具体的,可以参照下面的域categories

import org.apache.solr.client.solrj.beans.Field;    
 public class Item {    
    @Field    
    String id;    
    @Field("cat")    
    String[] categories;     
    @Field    
    List<String> features;     
  }    

java注释也可以使用在setter方法上,如下面的例子:

@Field("cat")    
 public void setCategory(String[] c){    
     this.categories = c;    
 }  
  

这里应该要有一个相对的,get方法(没有加java注释的)来读取属性

Item item = new Item();    
item.id = "one";    
item.categories =  new String[] { "aaa", "bbb", "ccc" };   

添加给solr

server.addBean(item);  
  

将多个bean提交给solr

List<Item> beans ;    
//add Item objects to the list    
server.addBeans(beans);  
     

注意:你可以重复使用SolrServer,这样可以提高性能。

6》

public static void update() {  
    SolrServer solrServer = null;  
    try {  
        solrServer = new CommonsHttpSolrServer(SOLR_URL);  
    } catch (MalformedURLException e) {  
        e.printStackTrace();  
    }  
    UpdateRequest updateRequest = new UpdateRequest();  
    SolrInputDocument sid = new SolrInputDocument();  
    sid.addField("id", 100000);  
    sid.addField("name", "struts+hibernate+spring 开发大全");  
    sid.addField("summary", "三种框架的综合应用");  
    sid.addField("author", "李良杰");  
    sid.addField("date", new Date());  
    sid.addField("content", "高级应用类书籍");  
    sid.addField("keywords", "SSH");  
    updateRequest.setAction(UpdateRequest.ACTION.COMMIT, false, false);    
    updateRequest.add(sid);    
    try {  
        UpdateResponse updateResponse = updateRequest.process(solrServer);  
        System.out.println(updateResponse.getStatus());  
    } catch (SolrServerException e) {  
        e.printStackTrace();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  
}  
提交一个document,采用更新方式,注意:
updateRequest.setAction(UpdateRequest.ACTION.COMMIT, false, false);  
7》
public static void query() {  
    SolrServer solr = null;  
    try {  
        solr = new CommonsHttpSolrServer(SOLR_URL);  
    } catch (MalformedURLException e) {  
        e.printStackTrace();  
        return;  
    }  
    // http://localhost:8983/solr/spellCheckCompRH?q=epod&spellcheck=on&spellcheck.build=true  
    ModifiableSolrParams params = new ModifiableSolrParams();  
    params.set("qt", "/spellCheckCompRH");  
    params.set("q", "编程");  
    params.set("spellcheck", "on");  
    params.set("spellcheck.build", "true");  
    QueryResponse response = null;  
    try {  
        response = solr.query(params);  
    } catch (SolrServerException e) {  
        e.printStackTrace();  
        return;  
    }  
    System.out.println("response = " + response);  
}  

这是一个查询方法。关键字:“编程”。关于查询的关键字,请参见slorwikihttp://wiki.apache.org/solr/QueryParametersIndex,或等待我的博客更新,在后面会有篇文章详细讲这个问题!

8》给solr的索引文件手动进行优化,
solr.optimize();  

9》solrJ提供了一组API,来帮助我们创建查询,下面是一个facetedquery的例子。

Java代码

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

所有的setter/add方法都是返回它自己本身的实例,所以就像你所看到的一样,上面的用法是链式的。

相关推荐