solr入门到放弃

Posted 杂文杂读

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了solr入门到放弃相关的知识,希望对你有一定的参考价值。

自认为乱中有序的一篇文章,文章内的相关参考链接请点击原文查看

1. Java 开发环境配置

2. Solr的安装与配置

一、安装

打开DOS,路径切换至solr_home\bin,执行命令:solr start –p 8888,将solr在8888端口运行,看到以下图片就证明solr启动成功了。(Solr默认端口为8983)

solr常用命令

solr start –p p_num   启动solr

solr restart –p p_num   重启solr

solr stop –p p_num   关闭solr

solr create –c c_name   创建一个核心

 

二、创建核心

每个核心都是solr的一个实例,一个solr服务可以创建多个核心,每个核心都可以进行自己独立配置。

三、schame   

schame文件可以对索引库的数据类型进行定义,对字段是否进行索引、储存等进行设置,要针对核心单独进行配置。schame的数据类型基本够用,如果不能满足需求,比如说对中文分词、拼音分词等,就可以自定义分词器。

3.1 添加索引字段

3.2 配置中文分词器IKAnalyzer

F:\Users\Administrator\eclipse-workspace\solr\solr-8.1.1\server\solr-webapp\webapp\WEB-INF\classes

ext.dic文件中添加自定义词组 重启solr

四、导入索引数据(mysql数据库为例)

注意事项:

①关注控制台报错信息(已弃用,com.mysql.jdbc.Driver  改为  com.mysql.cj.jdbc.Driver

②查看logging报错信息(时区问题,serverTimezone=UTC

 

1、solr添加数据库字段对应的索引字段

2、打开solr页面,导入数据

 

3、检测数据是否导入成功

 

五、Java客户端solrJ的使用

5.1 导入pom

5.2 编写model

5.3 写测试代码

按条件单个查询

//查询name为“陈龙”的user

query.set("q","name:陈龙" );

多条件查询

//查询id为“1”,并且name为“陈龙”,或者age为“28”岁,或者爱好包含“钓鱼”的user

query.set("q","id:1 AND name:陈龙 OR age:28 OR hobby:钓鱼" );

过滤查询

//过滤查询,age为1到30岁的user

query.set("fq", "age:[1 TO 30]");

设置排序

//以age降序

query.addSort("age", SolrQuery.ORDER.desc);

设置分页

 //开始位置

 query.setStart(0);

 //每页3条

 query.setRows(3);

 3. solr查询 

.基本查询

查询的关键字,此参数最为重要,例如,q=id:1,默认为q=*:*

fl  指定返回哪些字段,用逗号或空格分隔,注意:字段区分大小写,例如,fl= id,title,sort

start  返回结果的第几条记录开始,一般分页用,默认0开始

rows  指定返回结果最多有多少条记录,默认值为 10,配合start实现分页

sort  排序方式,例如id  desc 表示按照 “id” 降序

wt  (writer type)指定输出格式,有 xml, json, php

fq  filter query)过虑查询,提供一个可选的筛选器查询。返回在q查询符合结果中同时符合的fq条件的查询结果,例如:q=id:1&fq=sort:[1 TO 5],找关键字id1 的,并且sort15之间的。

df   默认的查询字段,一般默认指定。

qt  query type)指定那个类型来处理查询请求,一般不用指定,默认是standard

indent   返回的结果是否缩进,默认关闭,用 indent=true|on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。

version   查询语法的版本,建议不使用它,由服务器指定默认值。

 

  二. Solr的检索运算符

“:”  指定字段查指定值,如返回所有值*:*

“?”  表示单个任意字符的通配

“*”  表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)

“~”  表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foamroams的单词;roam~0.8,检索返回相似度在0.8以上的记录。

AND||  布尔操作符

OR&&  布尔操作符

NOT!-(排除操作符不能单独与项使用构成查询)

“+”  存在操作符,要求符号”+”后的项必须在文档相应的域中存在²

( )  用于构成子查询

[]  包含范围检索,如检索某时间段记录,包含头尾,date:[201507 TO 201510]

{}  不包含范围检索,如检索某时间段记录,不包含头尾date:{201507 TO 201510}

   三. 高亮

h1  是否高亮,hl=true,表示采用高亮

hl.fl  设定高亮显示的字段,用空格或逗号隔开的字段列表。要启用某个字段的highlight功能,就得保证该字段在schema中是stored。如果该参数未被给出,那么就会高亮默认字段 standard handler会用df参数,dismax字段用qf参数。你可以使用星号去方便的高亮所有字段。如果你使用了通配符,那么要考虑启用hl.requiredFieldMatch选项。

hl.requireFieldMatch   如果置为true,除非用hl.fl指定了该字段,查询结果才会被高亮。它的默认值是false

hl.usePhraseHighlighter   如果一个查询中含有短语(引号框起来的)那么会保证一定要完全匹配短语的才会被高亮。

hl.highlightMultiTerm   如果使用通配符和模糊搜索,那么会确保与通配符匹配的term会高亮。默认为false,同时hl.usePhraseHighlighter要为true

hl.fragsize   返回的最大字符数。默认是100.如果为0,那么该字段不会被fragmented且整个字段的值会被返回。

 

  四. 分组

  这是facet的官方wiki,里面有facet各个参数的详细说明。所以这里只说一些常用的。

FacetSolr的核心搜索功能,主要是导航(Guided Navigation)、参数化查询(Paramatic Search)Facet的主要好处是在搜索的同时,可以按照Facet条件进行分组统计,给出导航信息,改善搜索体验。

Facet主要分为:Field Facet   Date Facet 两大类

1. Field Facet

facet 参数字段必须被索引

facet=on facet=true

facet.field  分组的字段

facet.prefix  表示Facet字段前缀

facet.limit   Facet字段返回条数

facet.offict  开始条数,偏移量,它与facet.limit配合使用可以达到分页的效果

facet.mincount  Facet字段最小count,默认为0

facet.missing  如果为ontrue,那么将统计那些Facet字段值为null的记录

facet.sort  表示 Facet 字段值以哪种顺序返回 .格式为 true(count)|false(index,lex)true(count) 表示按照 count 值从大到小排列,false(index,lex) 表示按照字段值的自然顺序 (字母 , 数字的顺序 ) 排列 . 默认情况下为 true(count)

 

2. Date Facet

    对日期类型的字段进行 Facet.  Solr 为日期字段提供了更为方便的查询统计方式 .注意 , Date Facet的字段类型必须是 DateField( 或其子类型 ). 需要注意的是 , 使用 Date Facet , 字段名 , 起始时间 , 结束时间 , 时间间隔这 4 个参数都必须提供 .

facet.date  该参数表示需要进行 Date Facet 的字段名 , facet.field 一样 , 该参数可以被设置多次 , 表示对多个字段进行 Date Facet.

facet.date.start 起始时间 , 时间的一般格式为 ” 2015-12-31T23:59:59Z”, 另外可以使用 ”NOW”,”YEAR”,”MONTH” 等等 ,

facet.date.end  结束时间

facet.date.gap 时间间隔,如果 start 2015-1-1,end 2016-1-1gap 设置为 ”+1MONTH” 表示间隔1 个月 , 那么将会把这段时间划分为 12 个间隔段 .

facet.date.hardend  表示 gap 迭代到 end 时,还剩余的一部分时间段,是否继续去下一个间隔. 取值可以为 true|false, 默认为 false.

    例 start 2015-1-1,end 2015-12-21,gap ”+1MONTH”, 如果hardend false,则,最后一个时间段为 2015-12-1 2016-1-1; 反之,如果 hardend true,则,最后一个时间段为 2015-12-1 2015-12-21.

 

  注意:Facet的字段必须被索引,无需分词,无需存储。无需分词是因为该字段的值代表了一个整体概念,无需存储是因为一般而言用户所关心的并不是该字段的具体值,而是作为对查询结果进行分组的一种手段,给出相关的分组信息,从而改善搜索体验。

 

4. Solr Facet 统计查询

一)概述

        Facet是solr的高级搜索功能之一,可以给用户提供更友好的搜索体验.在搜索关键字的同时,能够按照Facet的字段进行分组并统计。例如下图所示,你上淘宝,输入“电脑”进行搜索,就会出现品牌分类,价格范围等分类,这个就叫Facet。

二)Solr Facet类型 

1. facet_queries:代表自定义条件查询facet,类似数据库的count函数

2. facet_fields    :代表根据字段分组查询,类似数据库的group by count的组合

3. facet_dates :根据日期区间分组查询

4. facet_ranges:当然了,日期有区间,数字也有,这个就是根据数字分组查询

三)Solr Facet组件 

         Solr的默认requestHandler已经包含了Facet组件(solr.FacetComponent).如果自定义requestHandler或者对默认的requestHandler自定义组件列表,那么需要将Facet加入到组件列表中去.

四)facet query 

       Facet Query 用户自定义条件查询facet,他提供了非常灵活的Facet.通过facet.query参数,可以对任意字段进行筛选.下面通过实例来阐述。基本上他的用法,都会在我实例中体现出来

1. &facet=on  

2. &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]  

3. &facet.query=price:[* TO 5000]  

4. &facet.query=brand:联想 AND price:1100

5. &facet.field=brand 

6. &facet.field=price  

五)Field Facet 

       Facet字段通过在请求中加入facet.field参数加以声明,如果需要对多个字段进行Facet查询,那么将该参数声明多次.这就是类似于数据库的group by 加上count的功能,非常的灵活。对结果进行统计筛选

每个Facet字段设置查询参数.以下介绍的参数既可以应用于所有的Facet字段,也可以应用于每个单独的Facet字段.应用于单独的字段时通过下面语法实现

1. f.字段名.参数名=参数值  

facet.prefix参数应用于brand字段,可以采用如下形式

1. &facet.field=brand  统计品牌

2. &facet.field=price  统计价格

3. &f.brand.facet.prefix=联  返回品牌名“联”开头)

4. &f.price.facet.mincount=2--单独对某个字段起作用,把统计值小于2的过滤

 

上面介绍了facet.field参数,下面介绍field fact的其他参数

1. 1).facet.prefix  

2.     表示Facet字段值的前缀.比如facet.field=cpu&facet.prefix=Intel,那么对cpu字段进行Facet查询,返回的cpu都是以“Intel”开头的。  

3. 2).facet.sort  

4.     表示Facet字段值以哪种顺序返回.可接受的值为true(count)|false(index,lex). true(count)表示按照count降序; false(index,lex)表示按照字段值升序(字母,数字的顺序)排列.默认情况下为true(count).当facet.limit值为负数时,默认facet.sort= false(index,lex).  

5. 3).facet.limit  

6.     限制Facet字段返回的结果条数.默认值为100.如果此值为负数,表示不限制.  

7. 4).facet.offset  

8.     返回结果集的偏移量,默认为0.它与facet.limit配合使用可以达到分页的效果.  

9. 5).facet.mincount  

10.     限制了Facet字段值的最小count,默认为0.合理设置该参数可以将用户的关注点集中在少数比较热门的领域.相当于group by having  

11. 6).facet.missing  

12.     默认为””,如果设置为true或者on,那么将统计那些该Facet字段值为null的记录.  

13. 7).facet.method  

14.     取值为enumfc,默认为fc.该字段表示了两种Facet的算法,与执行效率相关.  

15.     enum适用于字段值比较少的情况,比如字段类型为布尔型,或者字段表示中国的所有省份.Solr会遍历该字段的所有取值,并从filterCache里为每个值分配一个filter(这里要求solrconfig.xml里对filterCache的设置足够大).然后计算每个filter与主查询的交集.  

16.     fc(表示Field Cache)适用于字段取值比较多,但在每个文档里出现次数比较少的情况.Solr会遍历所有的文档,在每个文档内搜索Cache内的值,如果找到就将Cache内该值的count加1.  

17. 8).facet.enum.cache.minDf  

18.     当facet.method=enum,此参数其作用,minDf表示minimum document frequency.也就是文档内出现某个关键字的最少次数.该参数默认值为0.设置该参数可以减少filterCache的内存消耗,但会增加总的查询时间(计算交集的时间增加了).如果设置该值的话,官方文档建议优先尝试25-50内的值.  

 

六) Date Facet   

 日期类型的字段在文档中很常见,如商品上市时间,货物出仓时间,书籍上架时间等等.某些情况下需要针对这些字段进行Facet.不过时间字段的取值有无限性,用户往往关心的不是某个时间点而是某个时间段内的查询统计结果. Solr为日期字段提供了更为方便的查询统计方式.当然,字段的类型必须是DateField(或其子类型)。

        需要注意的是,使用Date Facet时,字段名,起始时间,结束时间,时间间隔这4个参数都必须提供.与Field Facet类似,Date Facet也可以对多个字段进行Facet.并且针对每个字段都可以单独设置参数。

1. &facet.date=birthday  

2. &facet.date.start=2014-01-00T09:15:00Z  

3. &facet.date.end=2014-12-00T09:15:00Z  

4. &facet.date.gap=%2B1MONTH  

5. &facet.date.other=all 

6. &f.birthday.facet.mincount=3 --单独对某个字段起作用,把统计值小于3的过滤掉

 

Date Facet参数说明 

1. 1).facet.date  

2.     该参数表示需要进行Date Facet的字段名,与facet.field一样,该参数可以被设置多次,表示对多个字段进行Date Facet.  

3. 2).facet.date.start  

4.     起始时间,时间格式为1995-12-31T23:59:59Z  

5. 3).facet.date.end  

6.     结束时间.  

7. 4).facet.date.gap  

8.     时间间隔.如果start为2009-1-1,end为2010-1-1.gap设置为+1MONTH表示间隔1个月,那么将会把这段时间划分为12个间隔段.  

9.         注意+因为是特殊字符所以应该用%2B代替.  

10. 5).facet.date.hardend  

11.     取值可以为true|false,默认为false.它表示gap迭代到end处采用何种处理.举例说明start为2009-1-1,end为2009-12-25,gap为+1MONTH,  

12.     hardend为false的话最后一个时间段为2009-12-12010-1-1;  

13.     hardend为true的话最后一个时间段为2009-12-12009-12-25.  

14. 6).facet.date.other  

15.     取值范围为before|after|between|none|all,默认为none,before会对start之前的值做统计,after会对end之后的值做统计,between会对start至end之间所有值做统计.如果hardend为true的话,那么该值就是各个时间段统计值的和.none表示该项禁用.all表示before,after,all都会统计.  

七)Facet Range

      范围统计分组统计,跟Date Facet一样,只是他们定位的字段的类型不同,Data Fact是做日期的分组统计的,而Fact Range是做数字分组统计的,在次强调,是做数字分组统计的,对于字符串,日期是不可以的。

参数跟上面的Date Facet基本一致,如下,就不做解释了,参考Date Facet的各个参数

1. 1.  facet.range  

2. 2.  facet.range.start  

3. 3.  facet.range.end  

4. 4.  facet.range.gap  

5. 5.  facet.range.hardend  

6. 6.  facet.range.other  

7. 7.  facet.range.include  

 参考实例

1. &facet.range=price  

2. &facet.range.start=1000  

3. &facet.range.end=5000  

4. &facet.range.gap=1000  

5. &f.price.facet.mincount=2--单独对某个字段起作用,把统计值小于2的过滤掉  

八)key 操作符

上面已经介绍了facet的四类统计,下面介绍一下key,什么是key?

答:key操作符可以为Facet字段取一个别名。哦原来如此简单!

参考实例:

1. 参数  

2. &facet=true  

3. &facet.query=brand:联想 AND price:1100   

4. 返回结果  

5. "facet_counts":{  

6.     "facet_queries":{  

7.       "brand:联想 AND price:1100":1},  

8.     "facet_fields":{},  

9.     "facet_dates":{},  

10.     "facet_ranges":{}}}  

11. --------------------------------  

12. 参数  

13. &facet=true  

14. &facet.query={!key=联想}brand:联想 AND price:1100   

15. 返回结果  

16. "facet_counts":{  

17.     "facet_queries":{  

18.       "联想":1},  

19.     "facet_fields":{},  

20.     "facet_dates":{},  

21.     "facet_ranges":{}}}  

00001.  从上面可以看出来,这样可以让字段名统一起来,方便我们拿到请求数据后,封装成自己的对象

九)tag操作符和ex操作符

这个也非常的重要,看下应用场景,当查询使用filter query 或者q的时候,如果filter query的字段正好是Facet字段,那么查询结果往往被限制在某一个值内.

 

1. &fq=price:[1000 TO 2000]  

2. &facet.field=price  

   从返回的结果可以看到fq将查询的结果集限制在了price 在1000 至 2000之间,其他范围的统计没有实际意义。

    有些时候,用户希望把结果限制在某一个范围以内,又希望查看该范围外的概况,像上述情况,用户想把结果限制在(price)1000~2000之间,但是又想查看其他价格区间有多少产品。这个时候需要用到tag和ex操作符.tag就是把一个filter标记起来,ex(exclude)是在Facet的时候把标记过的filter排除在外.

参考实例 

1. &fq={!tag=aa}price:[1000 TO 2000]  

2. &facet.field={!ex=aa}price  

这样其它价格区间的统计信息就有意义了. 

Pivot查询

两个维度的叠加,比如我想统计每种品牌下各种颜色的手机都有多少个

参考实例 

1. &facet=true  

2. &facet.pivot=brand,color  维度的叠加统计

3. &facet.pivot={!key=bc}brand,color  取别名

 

Facet 字段设计

一、Facet字段的要求

        Facet的字段必须被索引.一般来说该字段无需分词,无需存储.

        无需分词是因为该字段的值代表了一个整体概念,如电脑的品牌”联想”代表了一个整体概念,如果拆成”联”,”想”两个字都不具有实际意义.另外该字段的值无需进行大小写转换等处理,保持其原貌即可.

        无需存储是因为一般而言用户所关心的并不是该字段的具体值,而是作为对查询结果进行分组的一种手段,用户一般会沿着这个分组进一步深入搜索.

 二、特殊情况(复制域、动态域)

          对于一般查询而言,分词和存储都是必要的.比如CPU类型“Intel 酷睿2双核 P7570”,拆分成“Intel”,“酷睿”,“P7570”这样一些关键字并分别索引,可能提供更好的搜索体验.但是如果将CPU作为Facet字段,最好不进行分词.这样就造成了矛盾,解决方法为,将CPU字段设置为不分词不存储,然后建立另外一个字段为它的COPY,对这个COPY的字段进行分词和存储.

1. <types>  

2.     <fieldType name="string" class="solr.StrField" omitNorms="true"/>  

3.     <fieldType name="tokened" class="solr.TextField" >  

4.         <analyzer>  

5.         ……  

6.         </analyzer>  

7.     </fieldType>  

8. </types>  

9. <fields>  

10.     <field name="cpu" type="string" indexed="true" stored="false"/>  

11.     <field name="cpuCopy” type=" tokened" indexed="true" stored="true"/>  

12. </fields>  

13. <copyField source="cpu" dest="cpuCopy"/> 

 

 

5. Solr Grouping / Field Collapsing(分组查询)

一、概述

      分组统计查询不同于分组统计(Facet),facet只是简单统计记录数,并不能为每组数据返回实际的数据回来,solr提供的grouping查询能够解决这一问题,也就是说,他除了能分组外,还能把每组数据返回来。

二、语法简介

参考实例一

1. q=*:* 

2. &group=true  

3. &group.query=price:[0 TO 3000]  

4. &group.query=price:[2000 TO *]  

5. &group.field=price  

6. &group.main=true   group统计条件都会失去作用

7. &rows=1 

 

 

6. solr同义词,停词,和扩展词库

同义词:搜索结果里出现的同义词。如我们输入还行,得到的结果包括同义词还可以

停止词:在搜索时不用出现在结果里的词。比如is a are 等,这些词会在句子中多次出现却无意义,所以在分词的时候需要把这些词过滤掉。

 

扩展词:在搜索结果里额外出现的词。扩展词只能是你输入词的本身或子串。比如我们 输入重庆开县人,正常分词得到的结果是重庆” “开县”“;当我们在扩展词里加入重庆开县时,分词的结果是重庆开县”“重庆” “开县”“

 

conf目录下的 synonyms.txt 中增加同义词

/usr/local/solr/tomcat/webapps/solr/WEB-INF/classes

ext_stopword.dic:扩展词词典

mydict.dic:停用词词典

 

7. Suggest联想词

需求:在Web端或移动设备上实现用户输入汉字或汉字的首字母,提供关联词提示参数说明:name:suggester的名字,如果设置多个,可以在请求中指定。lookupImpl:查找方式的具体实现dictionaryImpl:字典的具体实现field:搜索的字段sourceLocation:字典文件suggestAnalyzerFieldType:字段的类型buildOnOptimize:何时创建拼写索引suggest.count:返回的搜索结果的数量

8. Jetty安装

2.1 下载Jetty

2.2 运行Jetty

  执行以下代码,Jetty会在默认8080端口运行

cd $JETTY_HOME

java -jar start.jar

2.2.1 基础应用例子

  标准的Jetty应用,有一个demo-base的文件夹,可以不在$JETTY_HOME下运行Jetty,在demo-base文件夹下执行以下命令:

> cd $JETTY_HOME/demo-base/

> java -jar $JETTY_HOME/start.jar

 

2.2.2 创建一个新的Jetty基目录

 

9. PHP solr

PHP  solr

安装jre 安装solr 安装PHP solr扩展

 


以上是关于solr入门到放弃的主要内容,如果未能解决你的问题,请参考以下文章

ElasticSearcho从入门到放弃:简介, lucene,概念, 安装

ElasticSearcho从入门到放弃:简介, lucene,概念, 安装

ElasticSearcho从入门到放弃:简介, lucene,概念, 安装

gentoo从入门到放弃

cmake从入门到放弃

G1从入门到放弃(二)