最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解spring中使用solr的代碼實(shí)現(xiàn)

 更新時間:2017年05月24日 16:04:55   作者:周游列國之仕子  
本篇文章主要介紹了詳解spring中使用solr的代碼實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

在介紹solr的使用方法之前,我們需要安裝solr的服務(wù)端集群?;旧暇褪前惭bzookeeper,tomcat,jdk,solr,然后按照需要配置三者的配置文件即可。由于本人并沒有具體操作過如何進(jìn)行solr集群的搭建。所以關(guān)于如何搭建solr集群,讀者可以去網(wǎng)上查看其它資料,有很多可以借鑒。這里只介紹搭建完solr集群之后,我們客戶端是如何訪問solr集群的。

之前介紹過,spring封裝nosql和sql數(shù)據(jù)庫的使用,都是通過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進(jìn)行訪問。

首先:

引入solr的原生代碼api的jar包

<dependency> 
  <groupId>org.apache.solr</groupId> 
  <artifactId>solr-solrj</artifactId> 
  <version>4.7.2</version> 
</dependency> 

其次:

在spring的配置文件中配置我們solr的FactoryBean類,此類是作為我們編寫自己業(yè)務(wù)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中的數(shù)據(jù)結(jié)構(gòu)bean

再次:

編寫我們的SolrCloudServerFactoryBean類,其中使用了spring的FactoryBean<SolrServer>,和InitializingBean。關(guān)于這兩者的含義讀者可以參考其他資料,基本意思是spring容器在注冊該bean之前,需要進(jìn)行的一些初始化操作。通過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; 
  } 
 
} 

最后:

現(xiàn)在就可以編寫我們的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; 
 
  /** 
   * 創(chuàng)建索引 
   * 
   * @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值進(jìn)行主鍵查詢。 
   * @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; 
  } 
} 

當(dāng)然solr的api不止于此,我們此處只是羅列了一些比較常用的使用方法。對于solr的查詢,有以下幾點(diǎn)需要注意。

1.    solr生成查詢語句的時候,是有q查詢和fq查詢之分的。哪些查詢條件放在q查詢里,哪些查詢條件放在fq查詢里,對查詢的效率還是有較大的影響的。一般固定不變的查詢條件放在q查詢里,經(jīng)常變化的查詢條件放在fq里。上述代碼中validTag:1就放在了q查詢里,循環(huán)里的字符串filter則放在了我們的fq查詢里。

2.    solr查詢時,要了解solr服務(wù)器集群的配置文件中使用的是什么樣的分詞器,不同分詞器對模糊查詢的結(jié)果是有影響的。比如常見的IK分詞器和標(biāo)準(zhǔn)分詞器(如果我們有一個字段的名稱為:我是中國人,ik分詞器在solr里的存儲就成為了“我”,“中國人”,“中國”,“國人”。而標(biāo)準(zhǔn)分詞器則會存儲為“我”,“是”,“中”,“國”,“人”。如果我們使用全稱查詢,即查詢:我是中國人,兩者是沒有問題的。但是使用模糊查詢,比如查詢“*我是*”,則兩個分詞器分詞都查不出來結(jié)果,而如果我們的查詢條件是“*中國人*”則在ik分詞器下可以查詢出結(jié)果,在標(biāo)準(zhǔn)分詞器下查不出結(jié)果。)

3.    使用solr的過程中,需要定時執(zhí)行solr的optimize函數(shù)來清理磁盤碎片,否則會影響讀寫效率。對于optimize的參數(shù)建議為(false,false,5)。

4.    寫solr數(shù)據(jù)的時候,盡量使用createIndexBatch方法,這是因?yàn)閟olr在執(zhí)行寫入的時候,寫入一條數(shù)據(jù)和寫入多條數(shù)據(jù)都需要全量建索引,其執(zhí)行時間是差不多的。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解析使用jdbc,hibernate處理clob/blob字段的詳解

    解析使用jdbc,hibernate處理clob/blob字段的詳解

    本篇是對使用jdbc,hibernate處理clob/blob字段進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • springboot項(xiàng)目中mybatis-plus@Mapper注入失敗問題

    springboot項(xiàng)目中mybatis-plus@Mapper注入失敗問題

    這篇文章主要介紹了springboot項(xiàng)目中mybatis-plus@Mapper注入失敗問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • SpringBoot整個啟動過程的分析

    SpringBoot整個啟動過程的分析

    今天小編就為大家分享一篇關(guān)于SpringBoot整個啟動過程的分析,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java 中 getClass() 方法的使用與原理深入分析(對象類型信息)

    Java 中 getClass() 方法的使用與原理深入分析(對象類型信息)

    在 Java 編程中,getClass() 是一個非常重要的方法,它用于獲取對象的運(yùn)行時類信息,無論是調(diào)試代碼、反射操作,還是類型檢查,getClass() 都扮演著關(guān)鍵角色,本文將深入探討 getClass() 的使用方法、底層原理以及實(shí)際應(yīng)用場景,感興趣的朋友一起看看吧
    2024-12-12
  • Java編程實(shí)現(xiàn)調(diào)用com操作Word方法實(shí)例代碼

    Java編程實(shí)現(xiàn)調(diào)用com操作Word方法實(shí)例代碼

    這篇文章主要介紹了Java編程實(shí)現(xiàn)調(diào)用com操作Word方法實(shí)例代碼,代碼注釋很詳細(xì),在這里分給大家,需要的朋友可以參考下。
    2017-09-09
  • 聊一聊SpringBoot服務(wù)監(jiān)控機(jī)制

    聊一聊SpringBoot服務(wù)監(jiān)控機(jī)制

    這篇文章主要介紹了聊一聊SpringBoot服務(wù)監(jiān)控機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Spring強(qiáng)大事務(wù)兼容數(shù)據(jù)庫多種組合解決業(yè)務(wù)需求

    Spring強(qiáng)大事務(wù)兼容數(shù)據(jù)庫多種組合解決業(yè)務(wù)需求

    這篇文章主要為大家介紹了Spring強(qiáng)大事務(wù)兼容數(shù)據(jù)庫多種組合解決業(yè)務(wù)需求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • spring mvc 和ajax異步交互完整實(shí)例代碼

    spring mvc 和ajax異步交互完整實(shí)例代碼

    本篇文章主要介紹了spring mvc 和ajax異步交互完整實(shí)例代碼,簡單的AJAX+SpringMVC的異步交互小例子,有興趣的可以了解一下。
    2017-02-02
  • SpringBoot整合JWT的入門指南

    SpringBoot整合JWT的入門指南

    JWT全稱是json web token,它將用戶信息加密到 token 里,服務(wù)器不保存任何用戶信息,服務(wù)器通過使用保存的密鑰驗(yàn)證 token 的正確性,只要正確即通過驗(yàn)證,這篇文章主要給大家介紹了關(guān)于SpringBoot整合JWT的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • Java加載ICC文件的方法和示例代碼

    Java加載ICC文件的方法和示例代碼

    ICC文件,通常用于顏色管理,定義了如何將一個顏色空間轉(zhuǎn)換為另一個顏色空間,在Java中,我們可能需要加載這些文件來進(jìn)行顏色轉(zhuǎn)換或管理,本文將為您提供加載ICC文件的方法和示例代碼,需要的朋友參考下吧
    2023-08-08

最新評論

铁岭市| 大田县| 城步| 留坝县| 贵定县| 阜平县| 湄潭县| 海丰县| 上杭县| 衢州市| 荔波县| 兴宁市| 滕州市| 普兰店市| 景洪市| 平南县| 湘乡市| 永和县| 周宁县| 安阳县| 武隆县| 广宁县| 剑川县| 应城市| 张家港市| 岑溪市| 曲松县| 读书| 垫江县| 全南县| 酒泉市| 阿坝县| 甘孜县| 新龙县| 库车县| 嘉祥县| 宁阳县| 琼中| 麟游县| 黎城县| 屏东市|