1.7.4.3 Parsers
Parsers
除了主查询解析器外,还有一些其他的查询解析器可以使用或者和主查询解析器连合使用.这部分描述了其他查询解析器的细节,并且给出了一些例子:
大多数的解析器都可以使用局部查询参数的方式来表达(Local Parameters in query).
1.1 Block Join Query Parsers
有两种查询解析器支持block joins,这些查询解析器允许索引搜索关系内容.可以使用在你想索引子文档到父文档的地方.比如,一个博客包含父文档和作为其他评论的子文档.或者产品(products)作为父文档,大小(size),颜色(colors),其他种类(variations)作为子文档.在性能方面,索引索引文档之间的关系比在查询时尝试做连接更加有效,因为关系已经在索引中存储,不需要再计算.
注意:这些解析器的功能是新的,在未来有可能发生变化.
要使用这些解析器,文档必须索引有子文档,目前文档只能通过XML update handler来被索引成关系结构.这个XML结构允许<doc>元素中嵌套<doc>元素,也可以包含一个标志父文档的字段.
例子,这里是两个文档,还有它们的子文档:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<add> <doc> <field name="id">1</field> <field name="title">Solr adds block join support</field> <field name="content_type">parentDocument</field> <doc> <field name="id">2</field> <field name="comments">SolrCloud supports it too!</field> </doc> </doc> <doc> <field name="id">3</field> <field name="title">Lucene and Solr 4.5 is out</field> <field name="content_type">parentDocument</field> <doc> <field name="id">4</field> <field name="comments">Lots of new features</field> </doc> </doc> </add>
在这个例子中,我们使用字段content_type来标记父字段,我们也可以使用一个boolean字段来标记,如isParent是否为true.
1.2 Block Join Children Query Parser
这个解析器使用了一个查询,匹配了一些父文档,返回它们的子文档.它的解析语法:q={!childof=<allParents>}<someParents>.<allParents>是一个匹配父文档的过滤器,这里你可以定义一个字段和值来识别一个父文档.参数someParents确定一个匹配夫文档的查询,输出的是子文档:
使用上面文档的例子,我们可以构造一个查询如q={!childof="content_type:parentDocument"}title:lucene 结果响应中,我们只获取到一个文档:
<result name="response" numFound="1" start="0"> <doc> <str name="id">12344</str> <str name="comments">Lots of new features</str> </doc> </result>
1.3 Block Join Parent Query Parser
这个解析器使查询匹配子文档,返回父文档的结果.语法: q={!parentwhich=<allParents>}<someChildren>,对于参数allParents是匹配父文档的过滤器,someChildren是一个查询匹配部分或者全部子文档.
使用上面的例子,我们可以构造一个查询:q={!parentwhich="content_type:parentDocument"}comments:SolrCloud,响应结果:
<result name="response" numFound="1" start="0"> <doc> <str name="id">12341</str> <arr name="title"> <str>Solr adds block join support</str> </arr> <arr name="content_type"> <str>parentDocument</str> </arr> </doc> </result>
1.4 Boost Query Parser
BoostQParser继承了QParserPlugin,从输入的值中创建了一个带权重的查询.参数b是加权函数.
例子:
创建一个查询"foo",使用函数log(popularity)对其加权:
{!boost b=log(popularity)}foo
创建一个查询"foo",使用日期函数关联ReciprocalFloatFunction:
{!boost b=recip(ms(NOW,mydatefield),3.16e-11,1,1)}foo
1.5 Collapsing Query Parser
CollapsingQParser解析器是一个真正的快速过滤器,当结果集中有区别的组(groups)的数量比较高时,相比对solr的标准方法,它提供了要给更高性能的字段合并(collapsing).CollapsingQParser在它将结果集转向剩余的搜索组件之前,将压缩结果集为每组一个单独的文档,所以,所有的下游组件(faceting,highlighting)将使用这个压缩结果集.
基于最高得分(scores)的合并(collapse):
fq={!collapse field=<field_name>}
基于数字字段最小值的合并(collapse):
fq={!collapse field=<field_name> min=<field_name>}
基于数字字段最大值的合并(collapse):
fq={!collapse field=<field_name> max=<field_name>}
基于函数的最小最大值的合并(collapse),cscore()函数可以和CollapsingQParserPlugin一起使用,返回当前文档被合并(collapse)的得分.
fq={!collapse field=<field_name> max=sum(cscore(),field(A))}
使用一个空策略合并(collapse):
fq={!collapse field=<field_name> nullPolicy=<nullPolicy>}
这里有三个空策略:
ignore:在合并(collapse)字段中,删除带有空值的文档,这是默认的.
expand:在合并(collapse)字段中,将每个带有空值的文档作为一个单独的组.
collapse:合并所有的空值文档为一个单独的组.使用最高得分还活着最小/最大值.
CollapsingQParserPlugin完全支持QueryElevationComponent.但是,没有一种方式来展开(extend)组的一页结果,还并不是solr合并(collapse)功能的完全替代品.
1.6 Field Query Parser
字段查询解析器
FieldQParser继承了QParserPlugin.从输入值中创建了一个字段查询.如果合适的话,使用文本分析,构造一个短语查询.参数f指的就是查询的字段.
例子:
{!field f=myfield}Foo Bar
这个例子使用"foo"和"bar"创建了一个短语查询(假定字段myfield的分析器是一个以空格和小写term来分词的文本分析器),这个一般等价于Lucene的查询表达式:
myfield:"Foo Bar".
1.7 Function Query Parser
FunctionQParser继承了QParserPlugin.从输入值中创建一个函数查询.这里只有一种方式使用函数查询,其他的参考 Function Queries.
例子:
{!func}log(foo)
1.8 Function Range Query Parser
FunctionRangeQParser继承QParserPlugin.
参数:
l:最低界限,可选项
u:较高界限,可选项
incl:包含较低界限,true/false,默认为false.
incu:包含较高界限,true/false,默认为false.
这里可以关联为frange.如下示例:
{!frange l=1000 u=50000}myfield
fq={!frange l=0 u=2.2} sum(user_ranking,editor_ranking)
更多相关信息可以参考 Ranges over Functions in Solr1.4.
1.9 Join Query Parser
连合查询解析器
JoinQParser继承QParserPlugin.它允许通过连接操作符来规范文档之间的关系.这和关系型数据库中join(连接)的概念是不同的,因为没有信息去真正的被连接.一个比较合适的"SQL" 比喻是"inner query".
例子:
找到所有包含"ipod"的产品,连接(join)它们针对制造商(manufacturer)的文档,返回制造商的列表.
{!join from=manu_id_s to=id}ipod
找到所有name为 "belkin"的制造商文档,连接它们针对产品的文档,并且针对price小于12美元的过滤器:
q = {!join from=id to=manu_id_s}compName_s:Belkin
fq = price:[* TO 12]
更多关于连接查询的信息,参考Joins. Erick Erickson也写了一篇博客叫 solr 和joins ,主机是SearchHub.org.
1.10 Lucene Query Parser
LuceneQParser继承 QParserPlugin.它使用操作符q.op,默认操作符是"OR" or "AND",默认字段名df.
例子:
{!lucene q.op=AND df=text}myfield:foo +bar -baz
更多关于Lucene查询解析器的语法,参考Lucene javadocs
1.11 Max Score Query Parser
最大得分查询解析
MaxScoreQParser继承LuceneQParser.返回这个从句的最大得分.在tie=1.0 的DisjunctionMaxQuery查询中,它封装了所有的SHOULD clause(从句).任何MUST或者PROHIBITED从句通过as-is传递.没有boolean查询,如 NumericRange就不会通过LuceneQParser解析行为.
例子:
{!maxscore tie=0.01}C OR (D AND E)
1.12 Nested Query Parser
嵌套查询解析
NestedParser继承QParserPlugin.创建一个嵌套查询,具有通过本地参数重新定义类型的能力.这个解析器在这样的场合是非常有用的:在配置中指定默认值,让客户端声明关联它们.
例子:
{!query defType=func v=$q1}
如果q1参数是price,查询可以是对price字段的函数查询,如果q1参数是 {!lucene}inStock:true}},那么就会从 Lucene syntax string中创建term查询,使用inStock=true匹配文档.这些参数可以定义在solrconfig.xml中的默认部分:
<lst name="defaults" <str name="q1">{!lucene}inStock:true</str> </lst>
关于嵌套查询的更多性能,参考Nested Query In Solr.
1.13 Old Lucene Query Parser
OldLuceneQParser 继承 QParserPlugin.
例子:
{!lucenePlusSort} myfield:foo +bar -baz;price asc
1.14 Prefix Query Parser
前缀查询解析
PrefixQParser继承 QParserPlugin,对输入的值创建前缀查询.目前没有分析器(analysis)或者值转换器用来床架前缀查询,参数f指的是字段,前缀声明后面的字符串直接被当作通配符查询.
例子:
{!prefix f=myfield}foo
等价于Lucene查询解析器的表达式: myfield:foo*
1.15 Raw Query Parser
未加工的查询解析
RawQParser继承 QParserPlugin,不用任何分析器或者转换器,来创建一个term查询.使用环境:debugging,或者从terms组件中返回原始的terms.只有一个参数f,来定义搜索字段.
例子:
{!raw f=myfield}Foo Bar
构造的query查询是: TermQuery(Term("myfield","Foo Bar"))
1.16 Simple Query Parser
简单查询解析器
基于Lucene的SimpleQueryParser.这个查询解析器允许用户输入它们想要输入的查询,然后它将很好的解释这个查询,并返回结果.
q.operator:开启解析的指定操作,默认的所有的操作都是开启的,这可以按照需要关闭指定的操作,给这个参数传递一个空的字符串就可以关闭指定的操作.
操作符 | 描述 | 例子 |
+ | 指定AND | token1+token2 |
| | 指定OR | token1|token2 |
- | 指定NOT | -token3 |
" | 创建一个短语 | "term1 term2" |
* | 指定一个前缀查询 | term* |
~N |
在一个term的末尾,指定一个模糊查询 | term~1 |
~N | 在短语末尾,指定一个邻近(near)查询. | "term1 term2"~5 |
( ) | 指定查询优先级 | token1 + (token2 |token3) |
q.op:定义默认使用的操作符,一般情况下,默认的是OR,也可以使用AND来替换掉.
qf:查询字段列表
df:如果没有在schem.xml中定义的话定义默认查询字段.如果已经定义,覆盖这个默认字段.
任何语法错误都可以被忽略,这个查询解析器将会尽它所能的解释query.
1.17 Spatial Filter Query Parser
SpatialFilterQParser继承 QParserPlugin,创建一个空间过滤器,这个字段必须实现 SpatialQueryable.所有单位均为公里.
参数 | 描述 |
sfield | 过滤器字段,必填 |
pt | 参考点,必须匹配字段的尺寸.必填 |
d | 距离,单位km,必填 |
目前所用的距离量度取决于所述的FieldType,LatLonType默认使用haversine(半矢量).PointType默认使用Euclidean(2-norm).
例子:
{!geofilt sfield=<location_field> pt=<lat,lon> d=<distance>}
这是一些配置值的例子:
fq={!geofilt sfield=store pt=10.312,-20.556 d=3.5}
fq={!geofilt sfield=store}&pt=10.312,-20&d=3.5
fq={!geofilt}&sfield=store&pt=10.312,-20&d=3.5
如果和LatLonType一起使用geofilt,它能够生成的分数等于从点到字段的计算距离.使其作为一个主查询的组件和对查询加权非常有用.
1.18 Surround Query Parser
围绕查询解析器
SurroundQParser继承QParserPlugin.这个解析器提供了围绕查询语法的支持,它提供了邻近(proximity)搜索功能.这里边有两个操作:w创建了一个有序的跨度(距离),n创建了一个无序的跨度(距离).这两个操作都是一个数字值来声明两个term之间的距离.默认为1,最大是99.注意:查询字符串不能用任何方式分词.
例子:
{!surround} 3w(foo, bar)
这个例子将会查找文档中的terms"foo"和"bar"之间距离不会超过3个term.
这个查询解析器也可以接受布尔操作如(AND,OR,NOT或者是大写或者是小写),通配符,短语搜索的引号和加权.w和n操作也可以用大写或者小写表示.
更多关于这个解析器的操作参考:http://wiki.apache.org/solr/SurroundQueryParser
1.19 Switch Query Parser
SwitchQParser继承QParserPlugin.表现出来像"swithc" 或者"case" 状态.
在这个结果中每个查询结构都是XXX:
{!switch case.foo=XXX case.bar=zzz case.yak=qqq}foo
{!switch case.foo=qqq case.bar=XXX case.yak=zzz} bar // extra whitespace is trimmed
{!switch case.foo=qqq case.bar=zzz default=XXX}asdf // fallback to the default
{!switch case=XXX case.bar=zzz case.yak=qqq} // blank input uses 'case'
这个QParsePlugin的部分使用方法就是在SearchHandler的配置中指定appends的fq参数.使用下面的例子,客户端可以选择指定参数in_stock 和shipping来覆盖默认的过滤器行为.但是限制具体的合法值的集合.(shipping=any|free, in_stock=yes|no|all)
<requestHandler name="/select" class="solr.SearchHandler"> <lst name="defaults"> <str name="in_stock">yes</str> <str name="shipping">any</str> </lst> <lst name="appends"> <str name="fq">{!switch case.all='*:*' case.yes='inStock:true' case.no='inStock:false' v=$in_stock}</str> <str name="fq">{!switch case.any='*:*' case.free='shipping_cost:0.0' v=$shipping}</str> </lst> </requestHandler>
1.20 Term Query Parser
TermQParser继承QParserPlugin,从输入值中创建一个单独的term查询,相当于readableToIndexed().这是用于通过分面和terms组件从外部可读的terms中生成过滤器查询是很有用的.只有一个字段参数f.
例子:
{!term f=weight}1.5
对于文本字段,没有分析器做处理,因为原始的term已经从分面(facet)和terms组件中返回了.要对文本字段使用分析,参考上面的Field Query Parser.