在介绍solr的使用方法之前,我们需要安装solr的服务端集群。基本上就是安装zookeeper,tomcat,jdk,solr,然后按照需要配置三者的配置文件即可。由于本人并没有具体操作过如何进行solr集群的搭建。所以关于如何搭建solr集群,读者可以去网上查看其它资料,有很多可以借鉴。这里只介绍搭建完solr集群之后,我们客户端是如何访问solr集群的。
之前介绍过,spring封装nosql和sql数据库的使用,都是通过xxxTemplate。solr也不例外。
我们需要引入solr的jar包
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
</div>
然后引入solr在spring中封装的配置
<bean id="orderInfoSolrServer" class="com.xxxx.SolrCloudServerFactoryBean">
<property name="zkHost" value="${solr.zkHost}"/>
<property name="defaultCollection" value="orderInfo"/>
<property name="zkClientTimeout" value="6000"/>
</bean>
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate" scope="singleton">
<constructor-arg ref="orderInfoSolrServer" />
</bean>
<bean id="solrService" class="com.xxxx.SolrServiceImpl">
<property name="solrOperations" ref="solrTemplate" />
</bean>
</div>
然后重写我们的SolrServiceImpl就可以了。
但是,本文我们不用spring中封装的xxxTemplate这种格式做讲解。个人在使用spring封装solr的方式的时候遇到了各种各样的问题,可能是能力太low架控不了吧。下面我们主要讲解下如何使用solr的原生api进行访问。
首先:
引入solr的原生代码api的jar包
<dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>4.7.2</version> </dependency></div>
其次:
在spring的配置文件中配置我们solr的FactoryBean类,此类是作为我们编写自己业务service类的属性来操作solr。
<bean id="orderInfoSolrServer" class="com.xxxx.SolrCloudServerFactoryBean">
<property name="zkHost" value="${solr.zkHost}"/>
<property name="defaultCollection" value="orderInfo"/>
<property name="zkClientTimeout" value="6000"/>
</bean>
</div>
solr.zkHost是我们配置的zookeeper集群
orderInfo是我们存储在solr中的数据结构bean
再次:
编写我们的SolrCloudServerFactoryBean类,其中使用了spring的FactoryBean<SolrServer>,和InitializingBean。关于这两者的含义读者可以参考其他资料,基本意思是spring容器在注册该bean之前,需要进行的一些初始化操作。通过afterPropertiesSet方法可以看到我们在使用solr之前做的一些初始化操作。
package com.jd.fms.prism.solr.service;
import org.apache.http.client.HttpClient;
/**
* solrj spring integration
*
* @author bjchenrui
*/
public class SolrCloudServerFactoryBean implements FactoryBean<SolrServer>, InitializingBean {
private CloudSolrServer cloudSolrServer;
private String zkHost;
private String defaultCollection;
private int maxConnections = 1000;
private int maxConnectionsPerHost = 500;
private int zkClientTimeout = 10000;
private int zkConnectTimeout = 10000;
private Lock lock = new ReentrantLock();
public SolrServer getObject() throws Exception {
return cloudSolrServer;
}
public Class<SolrServer> getObjectType() {
return SolrServer.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, maxConnections);
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, maxConnectionsPerHost);
HttpClient client = HttpClientUtil.createClient(params);
LBHttpSolrServer lbServer = new LBHttpSolrServer(client);
lock.lock();
try {
if(cloudSolrServer == null) {
cloudSolrServer = new CloudSolrServer(zkHost, lbServer);
}
} finally {
lock.unlock();
}
cloudSolrServer.setDefaultCollection(defaultCollection);
cloudSolrServer.setZkClientTimeout(zkClientTimeout);
cloudSolrServer.setZkConnectTimeout(zkConnectTimeout);
}
public void setCloudSolrServer(CloudSolrServer cloudSolrServer) {
this.cloudSolrServer = cloudSolrServer;
}
public void setZkHost(String zkHost) {
this.zkHost = zkHost;
}
public void setDefaultCollection(String defaultCollection) {
this.defaultCollection = defaultCollection;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public void setMaxConnectionsPerHost(int maxConnectionsPerHost) {
this.maxConnectionsPerHost = maxConnectionsPerHost;
}
public void setZkClientTimeout(int zkClientTimeout) {
this.zkClientTimeout = zkClientTimeout;
}
public void setZkConnectTimeout(int zkConnectTimeout) {
this.zkConnectTimeout = zkConnectTimeout;
}
}
</div>
最后:
现在就可以编写我们的service类了,这里就是我们具体如何操作solr的地方。
package com.jd.fms.prism.solr.service.impl;
import com.jd.fms.prism.common.utils.DateUtil;
@Service("orderInfoSolrService")
public class OrderInfoNativeSolrServiceImpl {
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.FORMATER11);
private static SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(DateUtil.FORMATER4);
@Resource(name = "orderInfoSolrServer")
private SolrServer solrServer;
/**
* 创建索引
*
* @param orderInfo
*/
public void creatIndex(OrderInfo orderInfo) throws IOException, SolrServerException {
solrServer.addBean(orderInfo);
solrServer.commit();
}
/**
* 查询条件的生成。支持字段的精确查询,模糊查询,范围查询。
* @param orderIdfilter
* @param queryObj
* @param queryTimeList
* @param sorts
* @return
* @throws Exception
*/
public SolrQuery iniFilter(String orderIdfilter,OrderInfo queryObj,List<QueryTime> queryTimeList, Sort... sorts) throws Exception {
SolrQuery sQuery = new SolrQuery();
String queryQ = "validTag:1";
sQuery.setQuery(queryQ);
StringBuilder filter = new StringBuilder();
if(null != orderIdfilter){
filter.append(orderIdfilter);
queryObj.setOrderId(null);
}
//添加过滤条件
Field[] fields = queryObj.getClass().getDeclaredFields();
String fieldName = "";
String fieldValue = "";
for (Field field:fields){
if(field.isAnnotationPresent(org.apache.solr.client.solrj.beans.Field.class)){
field.setAccessible(true);
fieldName = field.getName();
fieldValue = String.valueOf(field.get(queryObj));
if (null != fieldValue && !"null".equals(fieldValue) && !"".equals(fieldValue) && !"0.0".equals(fieldValue)){
//如果是会员类型,则添加模糊查询
if(fieldName.equals("memberId") || fieldName.equals("orderType")){
fieldValue = "*" + fieldValue + "*";
}
filter.append(fieldName + ":" + fieldValue).append(" AND ");
}
}
}
if(queryTimeList!=null

