友情提示
Solr的内容还是比较多的,一篇文章只能讲解一部分。
全面介绍,没兴趣,没时间,也没能力,回报还不大。
本文只写点我认为比较重要的知识点,独特的个人想法。
仅供参考哦,更多细节需要自己去琢磨。

概述
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,
同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

工作方式
文档通过Http利用XML 加到一个搜索集合中。
查询该集合也是通过http收到一个XML/JSON响应来实现。
它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,
提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。

需求场景
查询和搜索,我们直接查询数据库MySQL。查询数据库主要有一些局限性:
比如多表查询效率低,大文本字段不好建立索引和搜索,复杂的条件查询和搜索功能不够强大,或者说不够简单。
使用Solr的话,就很简单地解决了以上问题。

以上需求,或者说关系型数据库mysql的问题,只是目前的一点理解。
虽说能够使用MySQL和Sorl解决实际中的问题,但毕竟都是中低难度的问题(自认为如此哦)。
非要说深入理解,剖析Solr的好处,MySQL是否“干的过”Solr,真心不懂。
单独搞MySQL,够你研究5年以上,DBA毕竟是个传说。
Solr,想搞懂,也得好多年。

个人同时学习Java服务端、Android、iOS、Web前端,目标是能够解决工作中最常见的问题,并不想要
深入学习有限的几种技术,比如MySQL,达到那种“再难的问题,也可以搞定”的程度。

我对Solr的8点理解
1.定义数据源接口,获得数据。

比如定义MySQL查询语句,把一个表或多个表的数据,导入到Solr中。
这个地方我觉得特别“不公平”,数据都是从别的地方搞过来的。外界的数据如果会变化,意味着,必须处理“数据同步”。
实时性要求不高的情况下,可以每天“全量更新”。要求高的情况下,单条数据的变化,需要“实时更新-单条”。
因此,Solr和Mysql并不是“直接竞争”关系,而是“互补”的关系。
2.把Mysql等数据源的数据,导入到Solr中去。
Solr定义数据,可以理解成一张很大的表,包含了很多字段,比如可以包含mysql中3个表的所有字段。
这样,查询就不存在“多表”的问题。
既然是一张表,建立索引,查询就很快了。
3.自带缓存功能。
Mysql,Solr,Redis等数据源或者有能力获得数据和管理数据的组件,只要需要,就可以提供“缓存”功能。
Solr简化了查询,缓存就更容易了。
4.索引和全文搜索。
Solr底层采用Lucene建立索引,全文索引,这样可以实现更多的“搜索功能”,可以说增强了Mysql的查询。
5.站内搜索的另外一种形式。
百度等搜索引擎,可以为网站提供“站内搜索”功能,他们爬去数据可以是公开的URL的形式。
如果需要和百度等合作,可以申请使用百度的搜索API,将站内数据,更友好,更快速地告诉百度。
而Solr和百度提供的搜索相关接口就基本一样,只不过是处在我们的管理之下。
6.简洁使用的管理界面。
后台有Web界面,导入数据,更新,可以通过可视化的操作来管理,比较方便。
7.功能服务化。
Solr提供的查询等功能,有Java等多种语言的实现。
建立数据结构,导入数据,维护缓存和实时性,最重要的就是“查询”和“搜索”了。
8.最大的“隐患”。
只用Mysql管理数据和查询的时候,我们必须并且只需要保障mysql的“高可用性”。
不能出任何问题,如果只用1个Mysql,意味着我们需要实时监控Mysql是否可用,如果出了问题,我们需要立即修复它。
如果是多台Mysql,我们需要用主从,或者更复杂的主从。

现在用了Solr,意味着,我们很多查询和搜索,优先使用Solr,不再使用Mysql。
这个时候,为了“高可靠性”,我们也必须保障Solr是靠谱的。
单台Solr服务器,可靠性怎么样,我不太清楚。
无论单台Solr是否靠谱,多台Solr更加靠谱,这都意味着
“我们程序中必须可靠的基础服务更多了”。

常见的必须“高可用性”的服务有
a.Mysql
b.Redis
3.Nginx
4.Solr
高可用性的服务越多,意味着我们的程序越复杂。
大部分的公司,都是中小型企业。
大部分的应用,都是为了快速推出,看看是否有效果。
真正需要保障“高可靠性”的项目,是很少的,如果遇到了,是很幸运的。

官方网站:http://lucene.apache.org/solr/
本地环境:Windows-5.3.1版本

运行和建立工程
启动:solr.cmd start(类似这样)
建立工程:
name=raikou
config=solrconfig.xml
schema=schema.xml
dataDir=J:\SoftData\Solr\raikou\data
指定config、schema等多种参数。
(图文并茂的入门指引,可以参考其它博主的文章,本人觉得这种“图文并茂”的太尼玛费事了。
方便了读者,但是“技术含量”不够高,博主表示不过瘾o(︶︿︶)o )

简要介绍下几个配置,附带源文件内容

core.properties

?
1
2
3
4
name=raikou(项目名称)
config=solrconfig.xml(Solr配置)
schema=schema.xml(模式定义)
dataDir=J:\SoftData\Solr\raikou\data (存储索引等数据)

Web界面输入的内容,保存在这了,入口配置,可以这么说。

schema.xml

?
1
2
3
4
<field indexed="true" multivalued="false" name="id" required="true" stored="true" type="long">
<field indexed="true" name="title" required="true" stored="true" type="string">
<field indexed="true" name="content" stored="true" type="string">
<field indexed="true" name="summary" stored="true" type="string"> </field></field></field></field>

定义了几个字段

id
title
唯一字段,默认查询字段

schemal.xml还配置了若干其它配置文件,比如“stopwords_en.txt”、“protwords.txt”、“stopwords.txt”等。
如果Solr启动报错,可能是缺少了这些字段。

data-config.xml

?
1
2
3
4
5
6
7
8
9
<!--?xml version=1.0 encoding=UTF-8?--> 
<dataconfig> 
<datasource driver="com.mysql.jdbc.Driver" password="mypassword/" type="JdbcDataSource" url="jdbc:mysql://localhost:3306/raikou?useUnicode=true&characterEncoding=UTF-8" user="root"
   
<document name="raikou_article">          
    <entity deltaimportquery="select" deltaquery="select" from="" id="${dih.delta.id}" name="raikou_article" query="select" raikou_article="" update_time="" where=""> '${dataimporter.last_index_time}'>                   
                <field column="id" name="id"
                <field column="title" name="title">
</field></field></entity></document></datasource></dataconfig>

定义了数据导入、增量更新的查询语句。

web.xml 这段配置,可能有用
E:Mongodb-Redis-Nginxsolr-5.3.1serversolr-webappwebappWEB-INFweb.xml

?
1
2
3
4
5
6
7
8
9
<!-- People who want to hardcode their Solr Home directly into the
      WAR File can set the JNDI property here...
  -->
  
   <env-entry>
      <env-entry-name>solr/home</env-entry-name>
      <env-entry-value>J:SoftDataSolr</env-entry-value>
      <env-entry-type>java.lang.String</env-entry-type>
   </env-entry>

Java程序访问
maven配置

?
1
2
3
4
5
<dependency>
        <groupid>org.apache.solr</groupid>
        solr-solrj</artifactid>
        <version>5.3.1</version>
    </dependency>

包名:org.apache.solr.client.solrj

工具类
SolrHelper.java 查询(查询语句构造和执行查询,分页查询),更新,重建索引

?
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.pagehelper.Page;
/**查询(查询语句构造),更新,重建索引*/
public class SolrHelper<t> {
    protected final Logger logger = LoggerFactory.getLogger(SolrHelper.class);
    private HttpSolrClient server;
    private StringBuffer queryString;
    public SolrHelper(String reqUrl) {
        server = new HttpSolrClient(reqUrl);
        queryString = new StringBuffer();
    }
    public void andEquals(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:).append(val);
    }
    public void orEquals(String fieldName, String val) {
        queryString.append( || ).append(fieldName).append(:).append(val);
    }
    public void andNotEquals(String fieldName, String val) {
        queryString.append( && ).append(-).append(fieldName).append(:)
                .append(val);
    }
    public void orNotEquals(String fieldName, String val) {
        queryString.append( || ).append(-).append(fieldName).append(:)
                .append(val);
    }
    public void andGreaterThan(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:[).append(val)
                .append( TO ).append(*]);
    }
    public void orGreaterThan(String fieldName, String val) {
        queryString.append( || ).append(fieldName).append(:[).append(val)
                .append( TO ).append(*]);
    }
    public void andGreaterThanOrEqualTo(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:[).append(val)
                .append( TO ).append(*]);
    }
    public void orGreaterThanOrEqualTo(String fieldName, String val) {
        queryString.append( || ).append(fieldName).append(:[).append(val)
                .append( TO ).append(*]);
    }
    public void andDateGreaterThan(String fieldName, Date val) {
        queryString.append( && ).append(fieldName).append(:[)
                .append(formatUTCString(val)).append( TO ).append(*]);
    }
    public void orDateGreaterThan(String fieldName, Date val) {
        queryString.append( || ).append(fieldName).append(:[)
                .append(formatUTCString(val)).append( TO ).append(*]);
    }
    public void andDateGreaterThanOrEqualTo(String fieldName, Date val) {
        queryString.append( && ).append(fieldName).append(:[)
                .append(formatUTCString(val)).append( TO ).append(*]);
    }
    public void orDateGreaterThanOrEqualTo(String fieldName, Date val) {
        queryString.append( || ).append(fieldName).append(:[)
                .append(formatUTCString(val)).append( TO ).append(*]);
    }
    public void andLessThan(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(val).append(]);
    }
    public void orLessThan(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(val).append(]);
    }
    public void andLessThanOrEqualTo(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(val).append(]);
    }
    public void orLessThanOrEqualTo(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(val).append(]);
    }
    public void andDateLessThan(String fieldName, Date val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(formatUTCString(val)).append(]);
    }
    public void orDateLessThan(String fieldName, Date val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(formatUTCString(val)).append(]);
    }
    public void andDateLessThanOrEqualTo(String fieldName, Date val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(formatUTCString(val)).append(]);
    }
    public void orDateLessThanOrEqualTo(String fieldName, Date val) {
        queryString.append( && ).append(fieldName).append(:[).append(*)
                .append( TO ).append(formatUTCString(val)).append(]);
    }
    public void andLike(String fieldName, String val) {
        queryString.append( && ).append(fieldName).append(:*).append(val)
                .append(*);
    }
    public void orLike(String fieldName, String val) {
        queryString.append( || ).append(fieldName).append(:*).append(val)
                .append(*);
    }
    public void andNotLike(String fieldName, String val) {
        queryString.append( && ).append(-).append(fieldName).append(:*)
                .append(val).append(*);
    }
    public void orNotLike(String fieldName, String val) {
        queryString.append( || ).append(-).append(fieldName).append(:*)
                .append(val).append(*);
    }
    public void andIn(String fieldName, String[] vals) {
        queryString.append( && );
        in(fieldName, vals);
    }
    private void in(String fieldName, String[] vals) {
        List<string> list=Arrays.asList(vals);
        in(queryString,fieldName,list);
    }
     
    public void orIn(String fieldName, List<string> vals) {
        queryString.append( || );
        in(queryString,fieldName,vals);
    }
    private static void in(StringBuffer queryString,String fieldName, List<string> vals) {
        queryString.append(();
        inStr(queryString, fieldName, vals);
        queryString.append());
    }
    private static void inStr(StringBuffer queryString, String fieldName,
            List<string> vals) {
        int index = 0;
        for (String val : vals) {
            if (0 != index) {
                queryString.append( || );
            }
            queryString.append(fieldName).append(:).append(val);
            index++;
        }
    }
     
    // http://stackoverflow.com/questions/634765/using-or-and-not-in-solr-query
    //instead of NOT [condition] use (*:* NOT [condition])
    public void andNotIn(String fieldName, String[] vals) {
        List<string> list=Arrays.asList(vals);
        queryString.append(&&();
        queryString.append(*:* NOT );
        inStr(queryString, fieldName, list);
        queryString.append());
    }
    public void andDateBetween(String fieldName, Date startDate, Date endDate) {
        queryString.append( && ).append(fieldName).append(:[)
                .append(formatUTCString(startDate)).append( TO )
                .append(formatUTCString(endDate)).append(]);
    }
    public void orDateBetween(String fieldName, Date startDate, Date endDate) {
        queryString.append( || ).append(fieldName).append(:[)
                .append(formatUTCString(startDate)).append( TO )
                .append(formatUTCString(endDate)).append(]);
    }
    public void andDateNotBetween(String fieldName, Date startDate, Date endDate) {
        queryString.append( && ).append(-).append(fieldName).append(:[)
                .append(formatUTCString(startDate)).append( TO )
                .append(formatUTCString(endDate)).append(]);
    }
    public void orDateNotBetween(String fieldName, Date startDate, Date endDate) {
        queryString.append( && ).append(-).append(fieldName).append(:[)
                .append(formatUTCString(startDate)).append( TO )
                .append(formatUTCString(endDate)).append(]);
    }
    public void andBetween(String fieldName, String start, String end) {
        queryString.append( && ).append(fieldName).append(:[).append(start)
                .append( TO ).append(end).append(]);
    }
    public void orBetween(String fieldName, String start, String end) {
        queryString.append( || ).append(fieldName).append(:[).append(start)
                .append( TO ).append(end).append(]);
    }
    public void andNotBetween(String fieldName, String start, String end) {
        queryString.append( && ).append(-).append(fieldName).append(:[)
                .append(start).append( TO ).append(end).append(]);
    }
    public void orNotBetween(String fieldName, String start, String end) {
        queryString.append( || ).append(-).append(fieldName).append(:[)
                .append(start).append( TO ).append(end).append(]);
    }
    public void andStartSub() {
        queryString.append( && ();
    }
    public void orStartSub() {
        queryString.append( || ();
    }
    public void endSub() {
        queryString.append());
    }
    private String formatUTCString(Date d) {
        SimpleDateFormat sdf = new SimpleDateFormat(yyyy-MM-dd'T'HH:mm:ss'Z');
        String s = sdf.format(d);
        return s;
    }
    public int execQueryTotalCount() {
        SolrQuery params = handleQuery();
        params.set(start, 0);
        params.set(rows, Integer.MAX_VALUE);
        QueryResponse response = null;
        try {
            response = server.query(params);
            return response.getResults().size();
        } catch (SolrServerException e) {
            logger.error(, e);
        } catch (IOException e) {
            logger.error(, e);
        }
        return 0;
    }
    public List<t> query(String sort, Class<t> beanClass) {
        SolrQuery params = handleQuery();
        QueryResponse response = null;
        List<t> list = null;
        try {
            logger.info(SolyQuery: + params.toString());
            response = server.query(params);
            list = (List<t>) response.getBeans(beanClass);
        } catch (SolrServerException e) {
            logger.error(SolrServerException, e);
        } catch (IOException e) {
            logger.error(IOException, e);
        }
        return list;
    }
    public Page<t> execQuery(Integer pageNo, Integer rows, String sort,
            Class<t> beanClass) {
        List<t> results = null;
        Page<t> page = null;
        SolrQuery params = handleQuery();
        if (pageNo != null && rows != null && pageNo > 0 && rows > 0) {
            params.set(start, (pageNo - 1) * rows);
            params.set(rows, rows);
        }
        if (null != sort && !.equals(sort)) {
            params.set(sort, sort);
        }
        QueryResponse response = null;
        try {
            logger.info(SolyQuery WithPage: + params.toString());
            response = server.query(params);
            results = (List<t>) response.getBeans(beanClass);
            page = new Page<t>(pageNo, rows, execQueryTotalCount());
            page.addAll(results);
        } catch (SolrServerException e) {
            logger.error(SolrServerException, e);
        } catch (IOException e) {
            logger.error(IOException, e);
        }
        return page;
    }
    private SolrQuery handleQuery() {
        SolrQuery params = new SolrQuery();
        String qryFinalStr = queryString.toString();
        if (qryFinalStr.startsWith( && )) {
            qryFinalStr = qryFinalStr.replaceFirst( && , );
        } else if (qryFinalStr.startsWith( || )) {
            qryFinalStr = qryFinalStr.replaceFirst( || , );
        }
        // 子查询开头的关联符号
        if (-1 != qryFinalStr.indexOf(( && )) {
            qryFinalStr = qryFinalStr.replaceAll(\( \&\& , ();
        }
        if (-1 != qryFinalStr.indexOf(( || )) {
            qryFinalStr = qryFinalStr.replaceAll(\( \|\| , ();
        }
        if (StringUtils.isBlank(qryFinalStr)) {
            qryFinalStr = *:*;
        }
        params.set(q, qryFinalStr);
        return params;
    }
    public void execDelete(String keyName, String keyVal) {
        try {
            server.deleteByQuery(keyName + : + keyVal);
            server.commit();
        } catch (SolrServerException | IOException e) {
            logger.error(, e);
        }
    }
    public void execUpdate(T model) {
        Field[] fields = model.getClass().getDeclaredFields();
        SolrInputDocument solrDoc = new SolrInputDocument();
        try {
            for (Field f : fields) {
                PropertyDescriptor pd;
                pd = new PropertyDescriptor(f.getName(), model.getClass());
                // 属性名
                String fieldName = f.getName();
                Method rM = pd.getReadMethod();// 获得读方法
                solrDoc.addField(fieldName, rM.invoke(model));
            }
            server.add(solrDoc);
            server.commit();
        } catch (Exception e) {
            logger.error(, e);
        }
    }
    public void execUpdate(SolrInputDocument solrDoc) {
        try {
            server.add(solrDoc);
            server.commit();
        } catch (SolrServerException e) {
            logger.error(, e);
        } catch (IOException e) {
            logger.error(, e);
        }
    }
    /**
     * 重建索引和增量索引的接口
     *
     * @param delta
     */
    public void buildIndex(boolean delta) {
        SolrQuery query = new SolrQuery();
        // 指定RequestHandler,默认使用/select
        query.setRequestHandler(/dataimport);
        String command = delta ? delta-import : full-import;
        String clean = delta ? false : true;
        String optimize = delta ? false : true;
        query.setParam(command, command).setParam(clean, clean)
                .setParam(commit, true).setParam(optimize, optimize);
        try {
            server.query(query);
        } catch (SolrServerException e) {
            logger.error(建立索引时遇到错误,delta: + delta, e);
        } catch (IOException e) {
            logger.error(建立索引时遇到错误,delta: + delta, e);
        }
    }
}</t></t></t></t></t></t></t></t></t></t></string></string></string></string></string></t>

代码使用示例:
1.常见的分页查询,更新单条数据

?
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
        SolrHelper<project> sh = new SolrHelper<project>(
                http://host/solr/project);
        sh.andEquals(id, 32404);
        List<project> page = sh.execQuery(1, 10, id desc,
                Project.class);
        Project ps = page.get(0);
        ps.setTotal(3.1415);
        sh.execUpdate(ps);
    }</project></project></project>

2.不修改,直接同步

?
1
2
3
4
5
6
public void synProject(long id) {
        ProjectSolrDto solrDto = projectMapper.selectSolrProjectSimple(id);
        SolrHelper<projectsolrdto> solrHelper = new SolrHelper<projectsolrdto>(
                solrProjectUrl);
        solrHelper.execUpdate(solrDto);
    }</projectsolrdto></projectsolrdto>

3.同步某几个字段

?
1
2
3
4
5
6
7
8
9
10
11
public void synIntention(Long id) {
        Intention intention = intentionMapper.selectByPrimaryKey(id);
        SolrHelper<intention> solrHelper = new SolrHelper<intention>(
                solrIntentionUrl);
        SolrInputDocument solrDoc = new SolrInputDocument();
        solrDoc.addField(id, intention.getId());
        solrDoc.addField(intro, intention.getIntro());
        solrDoc.addField(industry, intention.getIndustry());
        solrHelper.execUpdate(solrDoc);
    }
    </intention></intention>

4.删除

?
1
2
3
4
5
public void delFund(Long id) {
        SolrHelper<intention> solrHelper = new SolrHelper<intention>(
                solrFundUrl);
        solrHelper.execDelete(id, id.toString());
    }</intention></intention>

几点补充
1.需要有“定时器”,定时“全量更新”和“重建索引”,防止数据不一致,或者查询效率低。
2.SolrHelper中的代码,或者说Solr的相关代码,无非就是“增删改查CRUD”,比较特殊的
“重建索引”和为了执行查询,拼接查询条件的“And,Or”等工具方法。
3.分页有个实体类,用到了Github上的1个工具,个人觉得一般般,Page类的定义比较糟糕。
如有需要,自己引入,或者自行改造。

写在最后
IT互联网技术很多,更新很快,问题也很多,深入需要实践,深入需要时间。
技术方面的博学和专注,自己去平衡吧~
技术和技术之外的平衡,自己看着办哦~

转载于:https://www.cnblogs.com/duanxz/p/5208365.html

Solr入门和实践以及我对Solr的8点理解相关推荐

  1. Apache Solr入门教程(初学者之旅)

    2019独角兽企业重金招聘Python工程师标准>>> 写在前面:本文涉及solr入门的各方面,请逐行阅读,相信能帮助你对solr有个清晰全面的了解并能简单实用. 在Apache S ...

  2. Apache Solr入门教程

    转自:http://blog.csdn.net/u011936655/article/details/51960005 Apache Solr入门教程(初学者之旅) 写在前面:本文涉及solr入门的各 ...

  3. Spring Data Solr入门

    Spring Data Solr是Spring Data项目的扩展,该项目旨在简化Apache Solr在Spring应用程序中的使用. 请注意,这不是Spring(数据)或Solr的简介. 我认为您 ...

  4. solr入门以及dih简介

    Apache Solr 是一个开源的搜索服务器,本文介绍一些入门的基础知识,本来想直接写solrdih(dataImportHandler)组件的,但发现有些内容还是会涉及到solr的基础知识,因此也 ...

  5. solr入门之參考淘宝搜索提示功能优化拼音加汉字搜索功能

    首先看一下从淘宝输入搜索keyword获取到的一些数据信息: 第一张:使用拼音的全程来查询 能够看到提示的是匹配的转换的拼音的方式,看最后一个提示项 这里另一个在指定分类文件夹下搜索的功能,难道后台还 ...

  6. Solr入门之官方文档6.0阅读笔记系列(八) 相关过滤器

    第三部分 :   Understanding Analyzers, Tokenizers, and Filters Filter Descriptions You configure each fil ...

  7. solr入门之参考淘宝搜索提示功能优化拼音加汉字搜索功能

    http://blog.csdn.net/sqh201030412/article/details/51211551 首先看一下从淘宝输入搜索关键字获取到的一些数据信息: 第一张:使用拼音的全程来查询 ...

  8. Solr入门学习(二)—— Solr 的基本查询

    文章目录 一.数据准备 二.查询方式 1. Solr 管理界面查询 2. URL 查询 三.查询参数 四.运算符 五.查询示例 1. 关键词查询 2. 字段查询 3. 词组查询 4. 组合查询 六.更 ...

  9. solr和lucene_使用Apache Lucene和Solr 4进行下一代搜索和分析

    solr和lucene 六年前,我开始为developerWorks撰写有关Solr和Lucene的文章(请参阅参考资料 ). 多年来,Lucene和Solr确立了自己的坚如磐石的技术(Lucene作 ...

最新文章

  1. python 作用域 前缀_Python面试题:杂项内容
  2. 练习:卷积和池化过程中注意事项
  3. 7月1日 cf总结
  4. android复位机器人图片_Universal-Image-Loader 图片异步加载类库还不熟?
  5. springcloud-eureka简单实现
  6. 通过pgpool-II实现PostgreSQL数据库服务高可用
  7. rds mysql_Amazon RDS上MySQL
  8. Transactional replication-如何跳过一个事务
  9. 《剑指offer》面试题22——栈的压入、弹出序列(C++)
  10. Hive的下载和安装
  11. cad---菜单,工具栏,屏幕菜单,增强工具栏
  12. 安装mysql提示:由于找不到 MSVCR100.dll
  13. OpenGL入门学习[二] 绘制简单的几何图形
  14. HMM隐马尔可夫模型进行中文文本分词
  15. dseo13b打开自动消失_刚安装的WIN764位系统
  16. C++ 函数的声明和定义
  17. CoralGloba珊瑚跨境的“全银行通道结算”,是创举还是噱头?
  18. 2021年焊工(初级)考试资料及焊工(初级)免费试题
  19. laravel mysql超时时间_连接到数据库时Laravel连接超时
  20. csharp高级练习题:ASCII85编解码【难度:3级】--景越C#经典编程题库,不同难度C#练习题,适合自学C#的新手进阶训练

热门文章

  1. 移动端ios滚动卡顿问题
  2. HDU 2089 不要62 数位DP
  3. 微信分享自定义标题摘要和缩略图
  4. Loadrunner中socket协议中的三个关联函数
  5. 大亚DP607超级密码,破解方法
  6. SQL取出第 m 条到第 n 条记录的方法
  7. android studio 新建函数注释模板
  8. C++常用方法笔记资料
  9. hadoop集群崩溃恢复记录
  10. 一个老王开枪案例带你一步一步领略程序开发的魅力