SolrJ简述
Solr 允许客户端使用Http方式与服务端交互,同时也支持编程语言通信。SolrJ就是基于Java语言的交互实现,通过SolrJ编程接口,可以完成所有Solr支持的文档服务。
文章目标
通过对SolrJ编程接口学习,完成项目基本检索任务,包括索引,查询,分页,高亮,Facet。以下内容是基于 solr5.3.0版本的,请读者选择性阅读。
安装SolrJ
在使用SolrJ之前,需要确保相关包已经添加到类路径下,包安装有以下两种方式:
手动安装:
需要将 solr-5.3.0\dist 目录下的solr-solrj-5.3.0.jar(编译时)与 solrj-lib 文件夹中的包(运行时)添加到项目类路径下。
Maven安装:
<dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>5.3.0</version> </dependency>
SolrClient
SolrClient是SolrJ与服务端交互入口,它是一个抽象类,常用的实现类有两种:HttpSolrClient(standalone模式), CloudSolrClient(cloud模式)。使用形式如下:
SolrClient solr = new HttpSolrClient("http://my-solr-server:8983/solr/core1"); SolrClient solr = new CloudSolrClient("zkServerA:2181,zkServerB:2181,zkServerC:2181/solr");
客户端实例创建后,就可以向solr服务端提出交互请求了(如query, add, commit)。
索引文档
SolrJ文档索引工作也非常简单,可以通过以下两种方式实现:
SolrInputDocument:
首先创建与服务端的HTTP连接通道,即客户端,然后创建SolrInputDocument文档对象,再将文档提交给Solr。代码如下:
SolrClient solr = new HttpSolrClient("http://172.16.10.39:8983/solr/core1"); SolrInputDocument document = new SolrInputDocument(); document.addField("id", "552199"); document.addField("name", "Gouda cheese wheel"); document.addField("category", "1"); UpdateResponse response = solr.add(document); solr.commit();
注解:
注解的方式相对简洁,首先需要在Bean中使用Field注解:
public class MyBean { @Field public String id; @Field public String name; @Field public String category; }
然后再将Bean实例提交给solr:
SolrClient solr = new HttpSolrClient("http://172.16.10.39:8983/solr/core1"); solr.addBean(myBean); solr.commit();
需要注意的是,前面用到的三个域(id, name, category), 需要在 schema.xml文件中定义才能使用:
<field name="id" type="string" indexed="true" stored="true" required="true" /> <field name="name" type="text_general" indexed="true" stored="true"/> <field name="category" type=" string " indexed="true" stored="true"/>
此外,如果总是对大批量数据做索引工作的话,Solr建议使用ConcurrentUpdateSolrClient代替HttpSolrClient。
文档查询
文档查询工作是通过SolrQuery对象完成的,以下代码是搜索常用到的功能,包括关键字查询,分页,高亮,Facet:
SolrClient solr = new HttpSolrClient("http://172.16.10.39:8983/solr/core1"); SolrQuery q = new SolrQuery(); //在域name中搜索包含keyword的文档 String queryString = “name:keyword”; q.set("q", queryString); // 分页 q.set("start", 0); q.set("rows", 10); // Facet q.set("facet", true); q.set("facet.query",queryString); q.set("facet.field", "category"); //对category分类统计 q.set("facet.mincount", 1); //筛选命中文档数大于0的统计结果 // 高亮 q.set("hl", true); q.set("hl.fl", "name"); //需要高亮的域 q.set("hl.simple.pre", "<em>"); //高亮标签 q.set("hl.simple.post", "</em>"); // 提交查询 QueryResponse resp = solr.query(q); // 收集结果 long numFound = resp.getResults().getNumFound(); //命中文档数目 List<MyBean> list = resp.getBeans(MyBean.class); //命中文档结果(注解方式才能使用) List<FacetField> facetFields = resp.getFacetFields(); //Faceting 结果 Map<String, Map<String, List<String>>> highlight = resp.getHighlighting(); //高亮结果
从上面的代码可以看到,查询器语法与Solr Admin UI 中的参数一致,读者也可以使用SolrJ封装的方法调用。返回结果的结构也与Admin UI返回结果相似。以下是解析Facet, Highlight结果的示例代码,建议读者配合Admin UI返回结果查看:
// Faceting 结果处理 for (FacetField field : facetFields) { Log.debug("Field: " + field.getName() + " ,Count: " + field.getValueCount() + " : "); StringBuffer buf = new StringBuffer(); for (Count c : field.getValues()) { buf.append(c.getName() + ":" + c.getCount() + "\t"); } Log.debug(buf.toString()); } //Highlighting 结果处理 for (String docId : highlight.keySet()) { Map<String, List<String>> doc = highlight.get(docId); for (String fieldName : doc.keySet()) { List<String> fields = doc.get(fieldName); for (String val : fields) { Log.debug(docId + " -> " + fieldName + " -> " + val); } } }
小结
SolrJ是面向Solr服务端的编程库,通过SolrJ客户端对象SolrClient完成与Solr交互。介绍了SolrJ安装,索引文档(SolrInputDocument, 注解)及文档查询功能(查询,分页,高亮,Faceting)。
参阅文档
https://cwiki.apache.org/confluence/display/solr/Using+SolrJ
apache-solr-ref-guide-5.3.pdf