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

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

学习目标

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

Solr搜索流程介绍

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

搜索引擎(Solr-搜索详解)_第1张图片

Solr搜索的工作流程

搜索引擎(Solr-搜索详解)_第2张图片

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

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

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

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

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

参数元素说明

搜索引擎(Solr-搜索详解)_第3张图片

SearchHandler介绍

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


 query
 facet
 mlt
 highlight
 debug
 someothercomponent


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

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


  mycomponent


  myothercomponent

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

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

默认参数设置,如果你有这样的默认查询参数需要,可这样配置。

查询语法及解析器详解

搜索引擎(Solr-搜索详解)_第4张图片

通用查询参数详解

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

搜索引擎(Solr-搜索详解)_第5张图片

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

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

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

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

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

3、把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 词项修饰符:

搜索引擎(Solr-搜索详解)_第6张图片

范围查询:

    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 操作符

搜索引擎(Solr-搜索详解)_第7张图片

组合 () 

字句组合    (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支持非常灵活的表示方式:

搜索引擎(Solr-搜索详解)_第8张图片

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中都可以使用函数。

函数可以是

常量:数值或字符串字面值,如 10、”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.数据转换函数

搜索引擎(Solr-搜索详解)_第9张图片

 

2.数学函数

搜索引擎(Solr-搜索详解)_第10张图片

搜索引擎(Solr-搜索详解)_第11张图片

 

3.相关性函数

搜索引擎(Solr-搜索详解)_第12张图片

示例: 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.布尔函数

搜索引擎(Solr-搜索详解)_第13张图片

 

4.距离函数

搜索引擎(Solr-搜索详解)_第14张图片

搜索引擎(Solr-搜索详解)_第15张图片

 

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

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

 

搜索引擎(Solr-搜索详解)_第16张图片

什么是本地参数?

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

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
 

 

 

 

 

转载于:https://my.oschina.net/u/3728166/blog/3015715

你可能感兴趣的:(搜索引擎(Solr-搜索详解))