SolrJ是访问Solr的Java客户端框架,他提供添加索引、更新索引及搜索查询Solr的接口。以JAR包的方式提供。
搜索接口的调用实例
public class SolrSearch {
private static final String SOLR_URL = "http://localhost:8080/solr/"; // "http://10.0.8.10:8081/solr/spacearticle/"
private CommonsHttpSolrServer solrServer = null;
public SolrJSearch() {
try {
solrServer = new CommonsHttpSolrServer(SOLR_URL);
solrServer.setMaxTotalConnections(100);
solrServer.setSoTimeout(10000); // socket read timeout
solrServer.setConnectionTimeout(5000);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
public void search() {
SolrQuery query = new SolrQuery();
query.setQuery("A_Title:新浪科技");
// 新加条件(and的作用对TERM_VAL的6到8折的限制)
query.addFilterQuery("TERM_VAL:{6 TO 8 折}");
// 排序用的
// query.addSortField("price" , SolrQuery.ORDER.asc);
try {
QueryResponse rsp = solrServer.query(query);
SolrDocumentList docs = rsp.getResults();
System.out.println("文档个数:" + docs.getNumFound());
System.out.println("查询时间:" + rsp.getQTime());
for(SolrDocument doc : docs) {
String title = (String) doc.getFieldValue("A_Title");
Integer id = (Integer) doc.getFieldValue("A_ID");
System.out.println(id);
System.out.println(title);
}
} catch (SolrServerException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SolrJSearch sj = new SolrJSearch();
sj.search();
}
Solrj的使用说明
solrj被设计成一个可扩展的框架,用以向solr服务器提交请求,并接收回应。我们已经将最通用的一些命令封装在了solrServer类中了。
增加数据到Solr
首先需要获得一个server的实例:
SolrServer server = getSolrServer();
如果你使用的是一个远程solrServer的话,你或许会这样来实现getSolrServer()这个方法:public SolrServer getSolrServer() {
// the instance can be reused
return new CommonsHttpSolrServer();
}
如果你使用的是一个本地的solrServer的话,你或许会这样来实现getSolrServer()方法:
public SolrServer getSolrServer() {
// the instance can be reused
return new EmbeddedSolrServer();
}
如果,你在添加数据之前,想清空现有的索引,那么你可以这么做:
server.deleteByQuery("*:*"); // delete everything!
构造一个 document
SolrInputDocument doc1 = new SolrInputDocument();
doc1.addField("id" , "id1" , 1.0f);
doc1.addField("name" , "doc1" , 1.0f);
doc1.addField("price" , 10);
构造另外一个文档,每个文档都能够被独自得提交给solr,但是,批量提交是更高效的。每一个对SolrServer的请求都是http请求,当然对于EmbeddedSolrServer来说,是不一样的。
SolrInputDocument doc2 = new SolrInputDocument();
doc2.addField("id" , "id2", 1.0f);
doc2.addField("name" , "doc2", 1.0f);
doc2.addField("price" , 20);
构造一个文档的集合
Collection docs = new ArrrayList();
docs.add(doc1);
docs.add(doc2);
将documents提交给solr
server.add(docs);
提交一个commit
server.commit();
在添加完documents后,立即做一个commit,你可以这样来写你的程序:
UpdateRequest req = new UpdateRequest();
req.setAction(UpdateRequest.ACTION.COMMIT , flase , false);
req.add(docs);
UpdateResponse rsp = req.process(server);
使用java注释创建java bean
@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 features;
}
java注释也可以使用在setter方法上,如下面的例子:
@Field("cat")
public void setCategory(String[] c) {
this.categories = c;
}
这里应该要有一个相对的get方法(没有加java注释的)来读取属性。
获取服务器实例
SolrServer server = getSolrServer();
创建bean实例
Item item = new Item();
item.id = "one";
item.categories = new String[] {"aaa" , "bbb" , "ccc"};
添加给solr
server.addBean(item);
将多个bean提交给solr
List beans;
// add Item objects to the list
server.addBeans(beans);
注意:你可以重复使用SolrServer,这样可以提高性能。
读取数据从Solr中
获得solrserver的实例
SolrServer server = getSolrServer();
构造SolrQuery
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.addSortField("price" , SolrQuery.ORDER.asc);
向服务器发出查询请求
QueryResponse rsp = server.query(query);
获取结果。
SolrDocumentList docs = rsp.getResults();
想要以javabean的方式获取结果,那么这个javabean必须像之前的例子一样有java注释。
List bean = rsp.getBeans(Item.class);
创建查询
solrJ提供了一组API,来帮助我们创建查询,下面是一个faceted query的例子。
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方法都是返回它本身的实例,所以就像你所看到的一样,上面的用法是链式的。
使用SolrJ创建索引
Collection<SolrInputDocument> docs = new HashSet<SolrInputDocument>();
for(int i = 0 ; i < 10 ; i ++ ) {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("link" , "http://non-existent-url.foo/" + i + ".html");
doc.addField("source" , "Blog #" + i);
doc.addField("source-link" , "http://non-existent-url.foo/index.html");
doc.addField("subject" , "Subject:" + i);
doc.addField("title" , "Title:" +i);
doc.addField("content" , "This is the " + i + "(th|nd|rd) piece of content.");
doc.addField("category", CATEGORIES[rand.nextInt(CATEGORIES.length)]);
doc.addField("rating" , i);
// System.out.println("Doc[" + i "] is " + doc);
docs.add(doc);
}
以上代码中循环只是创建了SolrInputDocument(实际上是一个夸张的Map),然后给他添加Field。我将他添加到了一个集合中,这样一次就能将所有的文档发送到Solr。借助这个功能可以极大地加快索引的创建,并减少通过HTTP发送请求导致的开销。然后我调用了UpdateResponse response = server.add(docs);,他负责序列化文档并将其提交到Solr。UpdateResponse返回的值包含处理文档所用的时间的信息。为了让这些文档能够被搜索到,我又发出了一个提交命令:server.commit();。
Solr包的结构说明
CommonsHttpSolrServer
CommonsHttpSolrServer使用HTTPClient和solr服务器进行通信。
String url = "http://localhost:8983/solr";
SolrServer server = new CommonsHttpSolrServer(url);
Setting XmlResponseParser
solrJ目前使用二进制的格式作为默认的格式。对于solr1.2的用户通过显示的设置才能使用XML格式。
server.setParser(new XMLResponseParse());
Changing other Connection Settings
CommonsHttpSolrServer允许设置链接属性。
String url = "http://localhost:8983/solr";
CommonsHttpSolrServer server = new CommonsHttpSolrServer(url);
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.
EmbeddedSolrServer
EmbeddedSolrServer提供和CommonsHttpSolrServer相同的接口,他不需要http连接。
SolrCore core = SolrCore.getSolrCore();
SolrServer server = new EmbeddedSolrServer(core);
...
如果你想要使用Multicore特性,那么你可以这样使用:
File home = new File(getSolrHome());
File f = new File(home, "solr.xml");multicore.load(getSolrHome() , f);
EmbeddedSolrServer server = new EmbeddedSolrServer(multicore , "core name as defined in solr.xml");
注:如果你在你的项目中内嵌solr服务,这将是一个不错的选择。无论你能否使用http,他都提供相同的接口。