一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 詳解spring中使用solr的代碼實(shí)現(xiàn)

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

2020-10-28 15:04周游列國(guó)之仕子 JAVA教程

本篇文章主要介紹了詳解spring中使用solr的代碼實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

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

之前介紹過(guò),spring封裝nosql和sql數(shù)據(jù)庫(kù)的使用,都是通過(guò)xxxTemplate。solr也不例外。

我們需要引入solr的jar包

?
1
2
3
4
5
<dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-solr</artifactId>
      <version>1.0.0.RELEASE</version>
    </dependency>

然后引入solr在spring中封裝的配置

?
1
2
3
4
5
6
7
8
9
10
11
12
<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這種格式做講解。個(gè)人在使用spring封裝solr的方式的時(shí)候遇到了各種各樣的問(wèn)題,可能是能力太low架控不了吧。下面我們主要講解下如何使用solr的原生api進(jìn)行訪問(wèn)。

首先:

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

?
1
2
3
4
5
<dependency>
  <groupId>org.apache.solr</groupId>
  <artifactId>solr-solrj</artifactId>
  <version>4.7.2</version>
</dependency>

其次:

在spring的配置文件中配置我們solr的FactoryBean類,此類是作為我們編寫自己業(yè)務(wù)service類的屬性來(lái)操作solr。

?
1
2
3
4
5
<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是我們存儲(chǔ)在solr中的數(shù)據(jù)結(jié)構(gòu)bean

再次:

編寫我們的SolrCloudServerFactoryBean類,其中使用了spring的FactoryBean<SolrServer>,和InitializingBean。關(guān)于這兩者的含義讀者可以參考其他資料,基本意思是spring容器在注冊(cè)該bean之前,需要進(jìn)行的一些初始化操作。通過(guò)afterPropertiesSet方法可以看到我們?cè)谑褂胹olr之前做的一些初始化操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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的地方。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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);
    }
    //添加過(guò)濾條件
    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)){
          //如果是會(huì)員類型,則添加模糊查詢
          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中做聚合,做排序。而且整個(gè)過(guò)程都是秒級(jí)的。
   * @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);
 
    //添加分頁(yè)
    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不止于此,我們此處只是羅列了一些比較常用的使用方法。對(duì)于solr的查詢,有以下幾點(diǎn)需要注意。

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

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

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

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://blog.csdn.net/antao592/article/details/52807653

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品免费一级在线观看 | 乌克兰xxxxx 我要色色网 | 狠狠鲁视频 | 亚洲高清国产品国语在线观看 | np高h疯狂黄暴宫口 narutomanga玖辛奈之乳 | 日韩一卡2卡3卡新区网站 | 国产精品成人网红女主播 | 免费毛片在线观看 | 国产一区二区在线观看视频 | 成人动漫在线免费看 | 日本公与妇中文在线 | 色成人综合网 | 国产精品久久久久久五月尺 | 天天射久久 | 成年无限观看onlyfans | 精品久久香蕉国产线看观看麻豆 | 黄动漫车车好快的车车双女主 | 日本国产最新一区二区三区 | 国产精品香蕉夜间视频免费播放 | 欧美日韩色图 | 日韩视频免费一区二区三区 | 九九九国产视频 | 激情亚洲| 1986葫芦兄弟全集免费观看第十集 | 国产自拍专区 | 视频国产精品 | 国产精品一区久久精品 | 男人天堂999 | 亚洲国产精品第一区二区三区 | 精品久久99麻豆蜜桃666 | 我被黄总征服的全过程 | 我被黄总征服的全过程 | 成人18视频在线观看 | 欧美人shou交在线播放 | 精新精新国产自在现拍 | 吉泽明步高清无码中文 | 女子监狱第二季未删减在线看 | 国产最新进精品视频 | 911精品国产亚洲日本美国韩国 | 久久电影院久久国产 | 四虎影院免费在线播放 |