搜索引擎(Solr-搜索详解)

学习目标

1.掌握SOLR的搜索工做流程;
2.掌握solr搜索的表示语法及查询解析器
3.熟悉solr搜索的JSON格式 APIhtml

Solr搜索流程介绍

回顾,使用 lucene进行搜索的步骤:java

Solr搜索的工做流程web

查看内核的solrconfig.xml文件,了解搜索的请求处理器配置express

对比看_default、sample_techproducts_configs两种配置集的内核配置。apache

配置中的参数元素介绍见下一页。json

仔细查看techproducts 内核的solrconfig.xml的
/select
/query
/browse缓存

前面流程图中的各项工做都在哪里完成?
在SearchHandler
它是如何完成的?app

参数元素说明less

SearchHandler介绍electron

查询请求在SearcheHandler这个request handler中完成,各个步骤的工做由SearchHandler中组合的组件来完成了(可自定义,在该查询的requesthandler配置元素内配置)。示例,自定义组件组合:

<arr name="components">
 <str>query</str>
 <str>facet</str>
 <str>mlt</str>
 <str>highlight</str>
 <str>debug</str>
 <str>someothercomponent</str>
</arr>

"query" (usually QueryComponent)
"facet" (usually FacetComponent)
"mlt" (usually MoreLikeThisComponent)
"highlight" (usually HighlightComponent)
"stats" (usually StatsComponent)
"debug" (usually DebugComponent)

还可在主组件组合前、后加入组件:

<arr name="first-components">
  <str>mycomponent</str>
</arr>
<arr name="last-components">
  <str>myothercomponent</str>
</arr>

详细了解: https://wiki.apache.org/solr/SearchHandler

问:SearchHandler中配置的 default是作什么用的?

默认参数设置,若是你有这样的默认查询参数须要,可这样配置。

查询语法及解析器详解

通用查询参数详解

1.defType
defType用来选择解析参数q指定的主查询串的查询解析器,如未给定默认使用solr的标准查询解析器(defType=lucene)。
Solr中提供了三种解析器供选择:
lucene:   solr的Standard Query Parser  标准查询解析器
dismax:   DisMax Query Parser
edismax: Extended DisMax Query Parser (eDismax)

2.sort
指定如何对搜索结果进行排序,asc 表示圣墟,desc 降序。Solr可根据以下部分对结果文档进行排序:
文档相关性得分
函数计算的结果
设置了docValues="true"的基本数据类型字段(numerics, string, boolean, dates, etc.) 
存储了docValues的可排序分词索引字段(SortableTextFields)。
单值不分词索引的字段。
对于基本数据类型和SortableTextFields ,若是是多值的,排序规则:
升序:取最小值参与排序;
降序:取最大值进行排序;
如要指定用什么值:则在传参时用sort=field(name,max) or sort=field(name,min) 方式传参。

3.start
分页查询的起始行号(从0开始),没传默认为0。

4.rows
查询返回多少行,默认10(可配置)。

5.fq
Filter Query 用来在主查询的结果上进行过滤,不影响相关性评分。Fq对于提速复杂的查询很是有用。由于fq指定的过滤查询结果是独立于主查询被缓存起来的。对于下次查询,若是用到了该过滤查询,则直接从缓存中取出结果进行对主查询的结果进行过滤便可。

fq的传参说明:
能够一次传传多个fq:
	fq=popularity:[10 TO *]&fq=section:0
也可将多个过滤条件组合在一个fq:
	fq=+popularity:[10 TO *] +section:0

说明:几个fq就缓存几个过滤结果集

6.fl
fl(field list),指定结果中返回哪些字段,指定的字段必须是 stored="true" or docValues="true" 的。多个字段用空格或英文逗号间隔。须要评分时经过 score 指定。若是传人的值为*,则stored="true" or docValues="true" and useDocValuesAsStored="true"的字段都会返回。

7.debug
debug参数用于指定在结果中返回调试信息。

8.explainOther
在一个查询中附带解释另外一个查询的评分,在结果中返回它的得分解释。这可让咱们在topN查询时理解为何某个文档没有返回。
示例:
	q=supervillians&debugQuery=on&explainOther=id:juggernaut

9.timeAllowed
限定查询在多少毫秒内返回,若是到时间了还未执行完成,则直接返回部分结果。

10.omitHeader
true/false ,如设为true,在则响应体中忽略表示查询执行状态信息(如耗时)的头。

11.wt
指定响应的内容格式:json、xml、csv……  SearchHandler根据它选择ResponseWriter。

12.cache
设置是否对查询结果、过滤查询的结果进行缓存。默认是都会被缓存的。若是不须要缓存明确设置 cache=false。

13.logParamsList
solr默认会日志记录全部的请求参数,若是不须要记录全部,则经过此参数指定要记录的参数名,如:
	logParamsList=q,fq
若是都不记录:传入: logParamsList=

14.echoParams
指定在响应体的内容的头部中返回哪些查询参数,可选值:
explicit: 默认,返回显示传入的参数+
all: 应用到查询的全部参数.
none:不返回.

查询解析器介绍

Standard Query Parser
DisMax Query Parser
Extended DisMax Query parser

默认使用的是 Standard Query Parser 。经过defType参数可指定。

Standard Query Parser

solr标准查询解析器。关键优势:它支持一个健壮且至关直观的语法,容许咱们建立各类结构的查询。这个咱们在学习lucene时已学过。最大的缺点:它不能容忍语法错误。

Standard Query Parser  请求参数

除了通用参数外,标准查询解析器还支持的参数有:

q:用标准查询语法定义的查询表达式(查询串、主查询),必需。
q.op:指定查询表达式的默认操做, “AND” or “OR”,覆盖默认配置值。
df:指定默认查询字段
sow: Split on whitespace 按空格分割,若是设置为true,则会分别对分割出的文本进行分词处理。默认false。

Standard Query Parser  响应内容格式

请求:http://localhost:8983/solr/techproducts/select?q=id:SP2514N&wt=xml

Standard Query Parser  响应内容格式-练习

一、加上debug=all参数看看返回什么.

http://localhost:8983/solr/techproducts/select?q=cat:book&wt=xml&debug=all

二、加上explainOther参数看看返回什么

http://localhost:8983/solr/techproducts/select?q=cat:book&wt=xml&debug=all&explainOther=id:055357342X

三、把wt改成json看看与xml的不一样

http://localhost:8983/solr/techproducts/select?q=cat:book&wt=json&debug=all&explainOther=id:055357342X

标准查询语法:

Term 词项表示:

单个词项的表示:     电脑
短语的表示:     "联想笔记本电脑"

Field 字段:

字段名:
示例: name:“联想笔记本电脑” AND type:电脑
若是name是默认字段,则可写成: “联想笔记本电脑” AND type:电脑
若是查询串是:type:电脑 计算机 手机
注意:只有第一个是type的值,后两个则是使用默认字段。

Term Modifiers 词项修饰符:

范围查询:

    mod_date:[20020101 TO 20030101]       包含边界值
    title:{Aida TO Carmen}      不包含边界值

词项加权,使该词项的相关性更高,经过 ^数值来指定加权因子,默认加权因子值是1

示例:如要搜索包含 jakarta apache 的文章,jakarta更相关,则: jakarta^4 apache 短语也能够: "jakarta apache"^4 "Apache Lucene"

^=  固定分值,经过此字句匹配的文档使用固定的分值。

(description:blue OR color:blue)^=1.0 text:shoes

Boolean 操做符

组合 () 

字句组合    (jakarta OR apache) AND website

字段组合    title:(+return +"pink panther")

转义   \

对语法字符: + - && || ! ( ) { } [ ] ^ “ ~ * ? : \ /     进行转义。 如要查询包含 (1+1):2        \(1\+1\)\:2

注释,支持C语言风格的注释

"jakarta apache" /* this is a comment in the middle of a normal query string */ OR jakarta

Solr Standard Query Parser 对传统 lucene语法的加强

在范围查询的边界两端均可以用*

field:[* TO 100] finds all field values less than or equal to 100
field:[100 TO *] finds all field values greater than or equal to 100
field:[* TO *] matches all documents with the field

容许纯非的查询(限顶级字节)

-inStock:false   finds all field values where inStock is not false
-field:[* TO *]   finds all documents without a value for field

支持嵌入solr查询(子查询),切入查询可使用任意的solr查询解析器

inStock:true OR {!dismax qf='name manu' v='ipod'}

支持特殊的filter(…) 语法来讲明某个字句的结果要做为过滤查询进行缓存

q=features:songs OR filter(inStock:true)
q=+manu:Apple +filter(inStock:true)
q=+manu:Apple & fq=inStock:true

若是过滤查询中的某个字句须要独立进行过滤缓存,也可用。

q=features:songs & fq=+filter(inStock:true) +filter(price:[* TO 100])
q=manu:Apple & fq=-filter(inStock:true) -filter(price:[* TO 100])

范围查询 (“[a TO z]”), 前缀查询 (“a*”), 统配符查询(“a*b”)  使用规定分值。

查询中的时间表示语法,遵照前面讲索引时的规范

createdate:1976-03-06T23\:59\:59.999Z
createdate:"1976-03-06T23:59:59.999Z"
createdate:[1976-03-06T23:59:59.999Z TO *]
createdate:[1995-12-31T23:59:59.999Z TO 2007-03-06T00:00:00Z]
timestamp:[* TO NOW]
pubdate:[NOW-1YEAR/DAY TO NOW/DAY+1DAY]
createdate:[1976-03-06T23:59:59.999Z TO 1976-03-06T23:59:59.999Z+1YEAR]
createdate:[1976-03-06T23:59:59.999Z/YEAR TO 1976-03-06T23:59:59.999Z]

DisMax Query Parser

DisMax Query Parser 是设计用于处理用户输入的简单短语查询的,它的特色:

1 只支持查询语法的一个很小的子集:简单的短语查询、+  - 修饰符、AND OR 布尔操做; 
2 简单的语法,不抛出语法错误异常给用户。 
3 能够在多个字段上进行短语查询。
4 能够灵活设置各个查询字段的相关性权重。
5 能够灵活增长知足某特定查询文档的相关性权重。

DisMax:Maximum Disjunction  最大分离。

DisMax Query 定义:一个查询,能够为不一样字段设置评分权重,在合并它的查询字句的命中文档时,每一个文档的分值取各个字句中的最大得分值。

DisMax Query Parser参数说明

1.2查询参数说明
1.2.1q
指定主查询表达式。注意简单短语,不可以使用通配符,+号会被当成或处理。

1.2.2q.alt
q.alt 提供一个备选语句,当q没有指定或为空时,执行这个查询。

1.2.3qf
qf指定要查询的字段及权重。
qf="fieldOne^2.3 fieldTwo fieldThree^0.4"


1.2.4mm (Minimum Should Match)
mm 用来指定当q中包含多个字句、各字句是或操做时,最少需多少个字句匹配才算匹配。mm支持很是灵活的表示方式:

mm的默认值是100%。

1.2.5pf (Phrase Fields) 
pf用来设置当某个字段匹配全部查询字句的短语时,该字段的加权权重。定义格式同qf
pf="fieldOne^2.3 fieldTwo fieldThree^0.4"

1.2.6ps (Phrase Slop)
短语的移动因子。当查询给入多个词、短语时。对这些词进行短语匹配的移动因子。

1.2.7qs (Query Phrase Slop) 
用户给入的q 主查询中包含短语时,经过qs可指定短语的移动因子。

1.2.8tie (Tie Breaker)
这个tie参数一般是一个小于1的浮点数,当查询命中多个field的时候,最终的score得到多少将由这个tie参数来进行调节。好比命中了field1,field2这2个field。若是field1.score= 10,field2.score=3。那么 score = 10 + tie * 3.也就是说,若是tie=1的话,最终的score就至关于多个字段得分总和;若是tie=0,那么最终的score就至关因而命中的field的最高分。一般状况下呢,官方推荐tie=0.1。


1.2.9bq (Boost Query)
bq指定一个加权查询,当主查询中命中的文档符合bq加权查询时,将得到更高的得分。
q=cheese
bq=date:[NOW/DAY-1YEAR TO NOW/DAY]AND ^5.0 
bq=date:[NOW/DAY-1YEAR TO NOW/DAY]^5.0
bq=date:[NOW/DAY-1YEAR TO NOW/DAY]^5.0
能够指定多个bq参数。

1.2.10bf (Boost Functions) 
bf用来定义加权函数,而后可在bq中使用加权函数

bf=recip(rord(creationDate),1,1000,1000)
  ...or...
bq={!func}recip(rord(creationDate),1,1000,1000)


1.3DisMax Query Parser使用举例
1.使用StandardRequestHandler查询”video” http://localhost:8983/solr/techproducts/select?q=video&fl=name+score
2.配置了查询字段:text、features、name、id、manu、cat。并且匹配上name和cat会有更高的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video
3.能够将score显示出来,看一下各个文档的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video&fl=*,score
4.覆盖查询字段,并设置features有更高的得分,而text有较低的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video&qf=features^20.0+text^0.3
5.但愿某一字段在知足某一状况下有更高的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video&bq=cat:electronics^5.0


Extended DisMax Query Parser

扩展 DisMax Query Parse 使支标准查询语法(是 Standard Query Parser 和 DisMax Query Parser 的复合)。也增长了很多参数来改进disMax。
强烈建议:使用 edismax 来进行查询解析:
       支持的语法很丰富;
       很好的容错能力;
       灵活的加权评分设置。

请求参数说明

1.sow
sow:Split on whitespace 按空格拆分。若是设置为true,则对每一个单独的空格分隔的文本分别调用文本分析。默认是false;空格分隔的术语序列将一次性提供给文本分析,从而使分析筛选器的功能可以正常运行(如同义词处理)。
2.mm.autoRelax
如设置为true,当查询表达式的字句经分词过滤后在部分查询字段上(而非所有)减小字句了,最少匹配数自动放松。此参数用于解决因停用词过滤致使的查询不到文档的问题。

3.boost
加权函数查询,符合该查询的文档的得分=主查询得分 * 该加权查询得分。注意这里是乘。而 bq、bf是加
如根据各商品的热度对命中的商品文档加权
http://localhost:8983/solr/techproducts/select?defType=edismax&q=solr &pf=text&qf=text&boost=popularity

4.lowercaseOperators
true 支持 小写的 and  or。
1.2.5ps (Phrase Slop)
做为短语加权匹配时的移动因子,会做为 ps2  ps3的默认值。
ps=5

6.pf2
指定要进行二元组短语加权的字段及权重,相似pf,不一样之处:pf要求短语完整匹配,pf2是将查询的词分解为二元组进行短语匹配来加权。如查询的词为:solr based lucece java,pf2会对包含短语”solr based”或”based lucene”或”lucene java”的文档加权。
q= solr based lucece java&pf2=title^10 content^3&ps2=3 

7.ps2
pf2使用的移动因子,如未给定则使用ps。

8.pf3
指定要进行三元组短语查询加权的字段及权重。
如查询的词为:solr based lucece java 会被分为” solr based lucece”、” based lucece java”,在pf3指定的字段上进行短语匹配、加权。
q= solr based lucece java&pf3=title^10 content^3&ps3=2

9.ps3
pf3使用的移动因子,如未给定则使用ps。

10.stopwords
控制是否在查询的分析器中开启停用词过滤,默认是true。

11.uf
指定容许用户能够查询哪些字段以及开启嵌入查询支持,默认是全部字段、不可嵌入查询: uf=* -_query_。uf值支持通配符,以空格间隔多个字段。
示例:
  To allow only title field, use uf=title.
  To allow title and all fields ending with '_s', use uf=title *_s.
  To allow all fields except title, use uf=* -title.
  To disallow all fielded searches, use uf=-*.
  To allow embedded Solr queries (e.g. _query_:"…​" or _val_:"…​" or {!lucene …​}), you must expressly enable this by referring to the magic field _query_ in uf

查询字段别名

有时咱们在模式中定义的字段不适合直接给终端用户使用,如动态字段、很长的字段名(对用户使用不是很友好)。在eDismax中提供了查询字段别名机制,对用户更友好地写查询表达式,咱们在默认补充别名定义。如模式中的字段名为: title_t_zh 但愿以title 来给用户用。咱们能够经过 f.alias.qf=realField参数来定义别名。
示例:
defType=edismax&q=title:”lucene solr”&f.title.qf=title_t_zh

因是对查询字段取别名,能够更灵活的使用:
&f.who.qf=name^20 author^30&f.what.qf=cat^5 job^10
用户在写q时能够这样写 q=who:(mike tony) what:(动脑)
defType=edismax&q=who:(mike tony) what:(动脑)&f.who.qf=name^20 author^30&f.what.qf=cat^5 job^10&debug=all

示例

根据文档的流行度提高查询词 “hello” 的结果:
http://localhost:8983/solr/techproducts/select?defType=edismax&q=ipod&pf=text&qf=text&boost=popularity

使用负的boost
http://localhost:8983/solr/techproducts/select?defType=edismax&q=ipod&pf=text&qf=text&boost=sub(0,popularity)
搜索 iPod 或视频:
http://localhost:8983/solr/techproducts/select?defType=edismax&q=ipod+OR+video
在多个字段中搜索,指定(经过 boosts)每一个字段相对于彼此的重要性:
http://localhost:8983/solr/techproducts/select?q=video&defType=edismax&qf=features^20.0+text^0.3
您能够提升具备与特定值匹配的字段的结果:
http://localhost:8983/solr/techproducts/select?q=video&defType=edismax&qf=features^20.0+text^0.3&bq=cat:electronics^5.0
使用“mm”参数,1和2个单词查询要求全部可选子句匹配,但对于具备三个或更多子句的查询,容许使用一个缺失子句:
http://localhost:8983/solr/techproducts/select?q=belkin+ipod&defType=edismax&mm=2
http://localhost:8983/solr/techproducts/select?q=belkin+ipod+gibberish&defType=edismax&mm=2
http://localhost:8983/solr/techproducts/select?q=belkin+ipod+apple&defType=edismax&mm=2
 

 

函数

solr查询也可以使用函数,可用来过滤文档、提升相关性值、根据函数计算结果进行排序、以及返回函数计算结果。在标准查询解析器、dismax、edismax中均可以使用函数。

函数能够是

常量:数值或字符串字面值,如 十、”lucene solr”
字段:  name  title
另外一个函数:functionName(…)
替代参数:
         q={!func}min($f1,$f2)&f1=sqrt(popularity)&f2=1

函数的使用方式有:

用做函数查询,查询参数值是一个函数表达式,来计算相关性得分或过滤

q={!func}div(popularity,price)&fq={!frange l=1000}customer_ratings

在排序中使用:

sort=div(popularity,price) desc, score desc

在结果中使用:

&fl=sum(x, y),id,a,b,c,score&wt=xml

在加权参数 bf、boost中使用来计算权重

q=dismax&bf="ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3"

在设置评分计算函数的特殊关键字 _val_ 中使用

q=_val_:mynumericfield    _val_:"recip(rord(myfield),1,2,3)"

Function Query 函数查询说明:

函数查询:指咱们在查询参数q、fq中使用了函数来改变相关性得分或过滤的一类特殊查询。函数对全部匹配的文档分别进行计算获得一个值做为一个加分值,加入到文档的相关性得分中。

改变评分:

方式一:整个查询就是一个函数表达式,匹配全部文档,文档的得分就是函数值

q=*:*
q={!func}div(popularity,price)&debug=all

说明:{!func} 说明q参数须要用func查询解析器来解析,func:Function Query Parser

方式二:值挂接,加入一个评分项,文档的得分=其余关键字得分 + 函数值

q=ipod AND _val_:"div(popularity,price)"&debug=all

方式三:查询解析器挂接(显示嵌套查询)

q=ipod AND _query_:"{!func}div(popularity,price)"&debug=all

方式四:查询解析器挂接(隐式嵌套查询)

q=ipod AND {!func  v ="div(popularity,price)"}&debug=all

经过函数来过滤文档:

若是须要对搜索结果进行过滤,只留下函数计算产生特定值的文档,能够选择函数区间解析器(Function Range query parser,简称frange)。在q/fq参数中应用frange 执行一个特定的函数查询,而后过滤掉函数值落在最低值和最高值范围以外的文档。

q={!frange l=0.01 u=0.1}div(popularity,price)&debug=all
q=ipod&fq={!frange l=0.05 u=0.1}div(popularity,price)&debug=all

Solr中提供的函数:

官网参考:https://lucene.apache.org/solr/guide/7_3/function-queries.html#product-function

​​​​​​1.数据转换函数

 

2.数学函数

 

3.相关性函数

示例: doc1:(fieldX:A B C) and doc2:(fieldX:A A A A):
docFreq(fieldX:A) = 2 (A appears in 2 docs)
freq(doc1, fieldX:A) = 4 (A appears 4 times in doc 2)
totalTermFreq(fieldX:A) = 5 (A appears 5 times across all docs)
sumTotalTermFreq(fieldX) = 7 in fieldX, there are 5 As, 1 B, 1 C
利用函数查询和相关性函数,咱们就能够自定义相关性计算模型。

 

4.布尔函数

 

4.距离函数

 

​​​​​​​5.自定义函数

Solr中实现自定义函数很是简单。步骤以下:
一、编写一个函数类,这个类继承ValueSource类,保证在搜索索引中的每一个文档都返回一个计算值。
二、编写ValueSourceParser类,它能够理解自定义函数的语法(在该类中你编写如何解析的逻辑),并将它解析成第1步自定义的ValueSource函数须要的变量。
三、向solrconfig.xml文件添加一个XML元素,定义自定义函数的名称及ValueSourceParser的类。当自定义函数经过函数名调用时,ValueSourceParser类将会解析ValuesSource中的输入。

 

什么是本地参数?

做为查询参数值的前缀,用来为查询参数添加元数听说明用的参数。看下面的查询:

q=solr rocks

如须要为这个查询说明是进行 AND 组合及默认查询字段是title:

q={!q.op=AND df=title}solr rocks

本地参数语法

做为查询参数值的前缀,用 {!key=value key=value} 包裹的多个key=value

本地参数用法示例

Query Type 的简写形式,type指定查询解析器

q={!dismax qf=myfield}solr rocks
q={!type=dismax qf=myfield}solr rocks

经过v 关键字指定参数值

q={!dismax qf=myfield}solr rocks
q={!type=dismax qf=myfield v='solr rocks'}

参数引用

q={!dismax qf=myfield}solr rocks
q={!type=dismax qf=myfield v=$qq}&qq=solr rocks

其余查询解析器

其余查询解析器,让咱们能够在查询中灵活根据须要以本地参数的方式选用。

请参考官网: https://lucene.apache.org/solr/guide/7_3/other-parsers.html

 

小结

如何来写一个查询?  掌握语法 q 如何指定查询字段?  Field:    df    qf  如何添加过滤条件?Fq     {!frange} 如何指定返回字段? fl 如何指定排序? sort 如何为某个词项、短语加权?词项、短语^5 如何为字段加权? qf=title^10   pf   pf2  pf3 如何用字段值来进行加权,如流行度、销量? _val_   _query_  函数查询 如何查看某个查询的调试信息? debug  

相关文章
相关标签/搜索