在介绍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>
然后引入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>
然后重写我们的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>
其次:
在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>
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;
}
}
最后:
现在就可以编写我们的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 && queryTimeList.size() > 0) {
Iterator<QueryTime> iterator = queryTimeList.iterator();
while(iterator.hasNext()) {
QueryTime queryTime = iterator.next();
String beginDate = simpleDateFormat.format(queryTime.getBeginTime().getTime());
String endDate = simpleDateFormat.format(queryTime.getEndTime().getTime());
filter.append(queryTime.getFieldName() + ":" + "[" + beginDate + " TO " + endDate + "] AND ");
}
}
if(filter.length()>0){
filter.delete(filter.length()-5, filter.length());
}
sQuery.addFilterQuery(filter.toString());
if(sQuery.toString().equals("")){
sQuery.setQuery("*:*");
}
return sQuery;
}
/**
* 查询代码,可以看到我们可以在solr中做聚合,做排序。而且整个过程都是秒级的。
* @param map
* @param queryObj
* @param queryTimeList
* @param page
* @param sorts
* @return
* @throws Exception
*/
public Page<OrderInfo> query(Map map,OrderInfo queryObj, List<QueryTime> queryTimeList, Pageable page, Sort... sorts) throws Exception {
SolrQuery sQuery = iniFilter(null,queryObj,queryTimeList);
//添加分页
if(page != null){
sQuery.setStart(page.getPageNumber()*page.getPageSize());
sQuery.setRows(page.getPageSize());
}
//添加排序
/*if (null != sorts){
sQuery.setSort("orderId",SolrQuery.ORDER.asc);
}*/
QueryResponse response = null;
sQuery.setGetFieldStatistics("orderPrice");
sQuery.setGetFieldStatistics("duePrice");
sQuery.setGetFieldStatistics("diffPrice");
try {
response = solrServer.query(sQuery);
} catch (SolrServerException e) {
e.printStackTrace();
}
SolrDocumentList list = response.getResults();
Map<String, FieldStatsInfo> mapSum = response.getFieldStatsInfo();
String orderPriceSum = null;
if(mapSum.get("orderPrice") != null && !mapSum.get("orderPrice").toString().equals("") ){
orderPriceSum = mapSum.get("orderPrice").getSum().toString();
}
String duePriceSum = null;
if(mapSum.get("duePrice") != null && !mapSum.get("duePrice").toString().equals("") ){
duePriceSum = mapSum.get("duePrice").getSum().toString();
}
String diffPriceSum = null;
if(mapSum.get("diffPrice") != null && !mapSum.get("diffPrice").toString().equals("") ){
diffPriceSum = mapSum.get("diffPrice").getSum().toString();
}
List<OrderInfo> list1 = new ArrayList<OrderInfo>();
DocumentObjectBinder binder = new DocumentObjectBinder();
Iterator iterator = list.iterator();
while(iterator.hasNext()){
OrderInfo orderInfo = binder.getBean(OrderInfo.class, (SolrDocument) iterator.next());
list1.add(orderInfo);
}
map.put("orderPriceSum", orderPriceSum);
map.put("duePriceSum", duePriceSum);
map.put("diffPriceSum", diffPriceSum);
Page<OrderInfo> pageList = new PageImpl<OrderInfo>(list1,page,list.getNumFound());
return pageList;
}
/**
* 我们可以按照key值进行主键查询。
* @param id
* @return
* @throws Exception
*/
public List<OrderInfo> queryByOrderId(String id) throws Exception {
SolrQuery sQuery = new SolrQuery();
String filter = "orderId" + ":" + id;
sQuery.setQuery(filter);
QueryResponse response = null;
try {
response = solrServer.query(sQuery);
} catch (SolrServerException e) {
e.printStackTrace();
}
SolrDocumentList list = response.getResults();
List<OrderInfo> list1 = new ArrayList<OrderInfo>();
DocumentObjectBinder binder = new DocumentObjectBinder();
Iterator iterator = list.iterator();
while(iterator.hasNext()){
OrderInfo orderInfo = binder.getBean(OrderInfo.class, (SolrDocument) iterator.next());
list1.add(orderInfo);
}
return list1;
}
public void deleteAll(OrderInfo orderInfo) throws IOException, SolrServerException {
String sQuery = "*:*";
solrServer.deleteByQuery(sQuery);
}
public void deleteById(String id) {
}
public void createIndexBatch(List<OrderInfo> orderInfoList) throws IOException, SolrServerException {
solrServer.addBeans(orderInfoList);
solrServer.commit();
}
public void deleteBySolrQuery(String solrQuery) throws IOException, SolrServerException {
solrServer.deleteByQuery(solrQuery);
solrServer.commit();
}
public SolrServer getSolrServer() {
return solrServer;
}
public void setSolrServer(SolrServer solrServer) {
this.solrServer = solrServer;
}
}
当然solr的api不止于此,我们此处只是罗列了一些比较常用的使用方法。对于solr的查询,有以下几点需要注意。
1. solr生成查询语句的时候,是有q查询和fq查询之分的。哪些查询条件放在q查询里,哪些查询条件放在fq查询里,对查询的效率还是有较大的影响的。一般固定不变的查询条件放在q查询里,经常变化的查询条件放在fq里。上述代码中validTag:1就放在了q查询里,循环里的字符串filter则放在了我们的fq查询里。
2. solr查询时,要了解solr服务器集群的配置文件中使用的是什么样的分词器,不同分词器对模糊查询的结果是有影响的。比如常见的IK分词器和标准分词器(如果我们有一个字段的名称为:我是中国人,ik分词器在solr里的存储就成为了“我”,“中国人”,“中国”,“国人”。而标准分词器则会存储为“我”,“是”,“中”,“国”,“人”。如果我们使用全称查询,即查询:我是中国人,两者是没有问题的。但是使用模糊查询,比如查询“*我是*”,则两个分词器分词都查不出来结果,而如果我们的查询条件是“*中国人*”则在ik分词器下可以查询出结果,在标准分词器下查不出结果。)
3. 使用solr的过程中,需要定时执行solr的optimize函数来清理磁盘碎片,否则会影响读写效率。对于optimize的参数建议为(false,false,5)。
4. 写solr数据的时候,尽量使用createIndexBatch方法,这是因为solr在执行写入的时候,写入一条数据和写入多条数据都需要全量建索引,其执行时间是差不多的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# spring
# solr
# 整合
# spring使用solr
# java多线程处理执行solr创建索引示例
# solr在java中的使用实例代码
# 详解java整合solr5.0之solrj的使用
# Solr通过特殊字符分词实现自定义分词器详解
# 放在
# 我是
# 都是
# 配置文件
# 是有
# 我们可以
# 可以看到
# 则会
# 就可以
# 的是
# 也不
# 不出
# 有很多
# 执行时间
# 数据结构
# 此类
# 分页
# 几点
# 重写
# 要了
相关文章:
电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?
建站主机如何选?性能与价格怎样平衡?
建站之星安装后如何自定义网站颜色与字体?
C#如何序列化对象为XML XmlSerializer用法
宝塔建站无法访问?如何排查配置与端口问题?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
实例解析Array和String方法
山东网站制作公司有哪些,山东大源集团官网?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
北京建设网站制作公司,北京古代建筑博物馆预约官网?
c++怎么用jemalloc c++替换默认内存分配器【性能】
如何选择适配移动端的WAP自助建站平台?
如何用AWS免费套餐快速搭建高效网站?
c# 在ASP.NET Core中管理和取消后台任务
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何用已有域名快速搭建网站?
如何确保FTP站点访问权限与数据传输安全?
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
建站主机CVM配置优化、SEO策略与性能提升指南
如何快速登录WAP自助建站平台?
定制建站流程解析:需求评估与SEO优化功能开发指南
免费视频制作网站,更新又快又好的免费电影网站?
如何用5美元大硬盘VPS安全高效搭建个人网站?
c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】
建站主机选购指南:核心配置与性价比推荐解析
,怎么在广州志愿者网站注册?
中山网站制作网页,中山新生登记系统登记流程?
c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
如何制作一个表白网站视频,关于勇敢表白的小标题?
英语简历制作免费网站推荐,如何将简历翻译成英文?
电商网站制作价格怎么算,网上拍卖流程以及规则?
C++时间戳转换成日期时间的步骤和示例代码
建站之星备案流程有哪些注意事项?
如何选择高效响应式自助建站源码系统?
建站之星如何助力网站排名飙升?揭秘高效技巧
怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
建站主机与服务器功能差异如何区分?
建站之星如何保障用户数据免受黑客入侵?
清除minerd进程的简单方法
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
如何在阿里云服务器自主搭建网站?
如何正确下载安装西数主机建站助手?
头像制作网站在线制作软件,dw网页背景图像怎么设置?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
怀化网站制作公司,怀化新生儿上户网上办理流程?
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
青岛网站建设如何选择本地服务器?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
*请认真填写需求信息,我们会在24小时内与您取得联系。