Solr默认的查询解析器使用的lucene解析器。
标准查询解析器的主要优势在于它支持强大且直观的语法,允许创建各种结构化的查询。与DisMax查询解析器相比,最大的缺点是它不能够容忍语法错误,而DisMax查询解析器比设计为尽可能少的返回错误。

标准查询解析器参数

除了公用查询参数、层面分析参数、高亮参数、匹配相似参数,标准查询解析器支持下表中描述的参数:

参数描述
q 定义一个使用标准查询语法的查询。(必需字段)
q.op指定查询短语默认操作符,覆盖`schema.xml`文件中定义的默认操作符。(`AND` 或 `OR`)
df指定一个默认查询字段,覆盖`schema.xml`文件中定义的默认查询字段。(q字段不明确指定字段时,使用该字段)

标准查询解析器的结果

默认情况下,标准查询解析器的结果包含一个未命名的 块。如果使用调试参数,那么会返回一个额外名为 “debug” 的 块,包含有用的调试信息,包括原查询语句,解析后的查询语句,和对 块中每个document的解释信息。如果explainOther字段也被使用,那么附加说明信息或被添加到所有的匹配document中。

结果示例

本节提供使用标准查询解析器的返回结果样例。
下面的URL请求一个简单的查询,请求使用使XML结果更可读的缩进方式的XML响应读取器。

http://localhost:8983/solr/techproducts/select?q=id:SP2514N

结果:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <responseHeader><status>0</status><QTime>1</QTime></responseHeader>
    <result numFound="1" start="0">
        <doc>
            <arr name="cat">
                <str>electronics</str><str>hard drive</str>
            </arr>
            <arr name="features">
                <str>7200RPM, 8MB cache, IDE Ultra ATA-133</str>
                <str>NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor</str>
            </arr>
            <str name="id">SP2514N</str>
            <bool name="inStock">true</bool>
            <str name="manu">Samsung Electronics Co. Ltd.</str>
            <str name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133</str>
            <int name="popularity">6</int>
            <float name="price">92.0</float>
            <str name="sku">SP2514N</str>
        </doc>
    </result>
</response>

下面的是一个使用限制字段列表的查询示例:

http://localhost:8983/solr/techproducts/select?q=id:SP2514N&fl=id+name

结果:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <responseHeader><status>0</status><QTime>2</QTime></responseHeader>
    <result numFound="1" start="0">
        <doc>
            <str name="id">SP2514N</str>
            <str name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133</str>
        </doc>
    </result>
</response>

指定标准查询解析器的条件

对标准查询解析器的查询被分解为检索词和操作符。有2种类型的检索词:单词和短语。

  • 单词是一个单独的词,例如 “test” 或 “hello”
  • 短语是一组由双引号包围的词组,如 “hello dolly”

多个检索词可以与布尔运算符组合在一起,形成更复杂的查询(如下所述):

注:
解析器用于查询分析单词或短语的方式与解析器用于索引分析单词或短语的方式一致是和重要的;否则,搜索时可能会出现难以预料的结果。也就是说,索引分析和查询分析时使用的analyzer应该一致。

条件修饰

根据需要,Solr支持多样的能够增加灵活度或精度的检索词模糊匹配。这些模糊匹配包括可以进行模糊查询或一般查询的通配符。下面的章节消息描述了这些修改。

通配符查询

solr标准查询支持在单词中使用一个或多个通配符。通配符可以应用与单词,但不能用于短语中。

通配符查询类型字符示例
单字符(匹配一个字符)?查询串为'te?t'的将匹配'test'和'text'
多字符(匹配0个或多个字符)*tes* -> test, testing, 或 tester。
te*t -> test 或 text.
*est -> pest 或 test

模糊查询

solr标准查询支持基于最小编辑距离算法的模糊查询。模糊查询可以查询到一个与指定模糊查询相似但不精确匹配的短语。进行模糊查询,只需要在检索词末尾添加~符号。比如,使用模糊查询与模糊查询roam相似的结果:roam~将匹配 roams, foam, 和 foams。它还将匹配 roam 这个词本身。
一个可选的距离参数指定的最大可编辑数介于0和2之间,默认为2。例如:roam~1将匹配roams 和 foam。但不会匹配 foams,因为这个结果需要指定编辑距离为2。

注:
在大多数情况下,多个词干(减少检索词使用词干)能产生与模糊搜索和通配符搜索类似的效果。

邻近查询

邻近查询将查询一个检索词与另一个检索词有指定距离的结果。
执行邻近查询,在查询检索词组最后添加符号和一个数值。比如,要查询文档中的 “apache” 和 “jakarta” 之间有10个单词:"jakarta apache"~10
这里所说的距离,是匹配指定检索词所需移动单词的数量。在上面的例子中,”apache” 和 “jakarta” 之间有10个词的距离则匹配。如果 “apache” 在 “jakarta” 前面,则需要更大的数,使 “apache” 能够在 “jakarta” 后面。

范围查询

范围查询需要指定一个检索字段的范围(上限和下限),将匹配出指定检索字段的值在该范围内的结果。范围查询可以包括或不包括上下限。如果是非数字字段,按照字典排序。比如,下面的例子是匹配所有的mod_date检索字段在20020101和20030101之间的结果(包括20020101和20030101):
mod_date:[20020101 TO 20030101]
范围查询不限于日期字段或数字格式,还可以查询非日期字段:
title:{Aida TO Carmen} 将会查询所有 titleAidaCarmen之间的文档(不包括AidaCarmen)。
通过括号决定是否包括上限和下限:

  • 方括号[]表示包含上限和下限;
  • 花括号{}表示不包含上限和下限;
  • 也可以同时使用两种括号,表示一个包含,一个不包含,比如:count:{ 1 TO 10 ]。

控制相关度查询

Lucene/Solr提供了基于短语发现的控制相关度查询。在你要查询的短语结尾使用脱字符^和加权因子来对单词加权。加权因子越大,单词相关度越高。
加权查询允许通过加权单词控制文档的相关度。比如,你查询 “jakarta apache” ,并且希望 “jakarta” 相关度更高,你可以使用 ^ 符号,比如:jakarta^4 apache。你也可以对短语加权,比如:"jakarta apache"^4 "Apache Lucene"
默认,加权因子是1。尽管加权因子必须是正数,但是可以小于1(比如,0.2)。

使用^=打分

常量打分查询使用 <query_clause>^=<score>,对整个变量设置指定分值。当你只关心一个特定的匹配条件,不希望其他因素产生影响,比如检索词频率或逆文献频率。比如:(description:blue OR color:blue)^=1.0 text:shoes

在标准查询时指定字段

在Solr索引数据组织的领域,这是在Solr SCHEMA.XML 文件定义。搜索可以利用字段添加到查询的精度。 例如, 你可以在一个特定的领域寻找一个术语, 比如一个标题字段。
在solr中对数据创建索引是以字段为基准的,这是在solr的schema.xml文件中定义的。 搜索可以利用字段增加查询精度。比如,你可以指定一个字段来搜索检索词查询一个,比如一个title字段。
schema.xml文件中定义一个字段作为默认字段。如果你在查询的时候没有指定字段,solr只搜索默认字段。另外,你可以在查询过程中指定一个字段或字段组合。
要指定一个字段,只需要在检索词前面加上字段和冒号(:),然后就能够使用这个字段进行查询了。
比如,假设一个索引包括两个字段,titletext,并且text是默认字段。如果你想查询查询名为The Right Way的文档和包含don't go this way的文档,你可以使用下面的检索方法:

title:"The Right Way" AND text:"don't go this way"
title:"Do it right" AND "don't go this way"

既然text是默认字段,可以不用明确指明;所以,上面第二种方式忽略它。
默认字段先于指定字段,所以查询title:Do it right将只在title字段查询Do,在默认字段上查询itright

标准查询支持的布尔运算符

布尔运算符可以在查询时使用布尔逻辑,在匹配文档时查询存在或不存在指定检索词或条件。下面的表格总结了标准查询可以使用的布尔运算符。

布尔运算符替代符号描述
AND&&要求在布尔运算符两侧的任何一方都要匹配。
NOT!要求对应搜索词不存在。
OR||要求布尔运算符两侧一个或两个检索词都会出现。
+要求符号”+”后的项必须在文档相应的域中存在
-要求符号”-”后的项不存在。与布尔运算符`!`的功能相似,是主流搜索引擎(如谷歌,比较了解用户社区)常用运算符。

布尔运算符允许使用逻辑运算符的组合检索词。Lucene支持AND+ORNOT-作为逻辑运算符。

注:
当使用关键词(如ANDNOT)指定布尔表达式时,必须使用大写字母。
标准查询支持上面列出的所有布尔运算符。DisMax查询只支持+-

布尔运算符OR (||)

OR运算符是默认运算符。这就意味着,如果两个检索词之间没有布尔表达式,默认使用OR运算符。OR运算符链接的两个检索词,如果任何一个检索词存在文档中,这个文档将成为匹配文档。这就相当于并集。可以使用||代替OR
schema.xml文件中,可以指定哪个符号代替布尔运算符,比如OR。查询包含 “jakarta apache” 或 “jakarta,”,可以使用
"jakarta apache" jakarta"jakarta apache" OR jakarta

布尔运算符AND (&&)

AND操作要求在一个文档中包含两个检索词。这相当于交集。可以使用&&代替AND
要查询包含 “jakarta apache” 和 “Apache Lucene”的文档,可以使用 "jakarta apache" AND "Apache Lucene""jakarta apache" && "Apache Lucene"

布尔运算符NOT (!)

NOT运算符不包括那些包含NOT之后的检索词的文档。这相当于差集。可以使用!代替NOT
要查询包含 “jakarta apache” 但不包括 “Apache Lucene”的文档,可以使用 "jakarta apache" NOT "Apache Lucene""jakarta apache" ! "Apache Lucene"

布尔运算符+

+要求+之后检索词存在于至少一个文档的某个字段中,以便查询返回。
比如,要查询文件,必须包含”jakarta”,可能或可能不包含”lucene”,可以使用查询:+jakarta lucene
这个操作符被标准查询和DisMax查询支持。

布尔运算符-

-或“禁止”运算符不包括符号后包含检索词的文件。
比如,要查询文件,必须包含”jakarta apache”,不包含”Apache Lucene”,可以使用查询:"jakarta apache" -"Apache Lucene"。

转义特殊字符

在solr的一次查询中,下列字符存在特殊含义:+ - && || ! ( ) { } [ ] ^ " ~ * ? : /
为了让solr解读这些字符时使用字面量,而不是特殊字符,可以在字符前加一个反斜杠\字符。例如,查询(1+1):2,为了不让solr把+、括号()对两个检索词进行子查询,需要在特殊字符前加上反斜杠转义字符:\(1\+1\)\:2

分组子查询

Lucene/Solr支持使用括号来组合子句形式的子查询。如果你想控制一个查询的布尔逻辑,这是非常有用的。
The query below searches for either “jakarta” or “apache” and “website”:
下面的查询搜索 “jakarta” 或 “apache” 和 “website”:(jakarta OR apache) AND website
这样增加了查询的准确性,”website”必须存在,需要”jakarta” 或 “apache” 存在。

group从句作为字段

在查询过程中多一个字段使用两个或多个布尔运算符,需要使用括号组织布尔从句。比如,下面查询title字段必须包含"return"单词和"pink panther"短语:title:(+return +"pink panther")

注释

在查询串中支持C语言风格的注释。比如:"jakarta apache" /* 这是在一个普通查询串中间的注释 */ OR jakarta
注释可以被嵌套。

Lucene查询和Solr标准查询的差别

Solr的标准查询与Lucene的查询的不同在以下几个方面:

  • *可用于指定个一个不确定返回的查询
    • field:[* TO 100] 查询所有小于等于100的数据
    • field:[100 TO *] 查询所有大于等于100的数据
    • field:[* TO *] 查询所有数据
  • 作为顶级从句时,允许纯否定(所有禁止从句)
    • -inStock:false 查询所有inStock不是false
    • -field:[* TO *] 查找所有文档
  • FunctionQuery语法。可以引用存在括号的方法的封装函数。
    • val:myfield
    • val:”recip(rord(myfield),1,2,3)”
  • 支持任何查询类型的嵌套从句
    • inStock:true OR {!dismax qf=’name manu’ v=’ipod’}
  • 范围查询(“[a TO z]”)、前缀查询(“a*”)和通配符查询(“a*b”)是常量打分(所有匹配的文件得到相同的分数)。评分因素TF、IDF、索引加权和坐标都没有使用。不限制检索词匹配次数(在Lucene的过去的版本)。

指定日期和时间

使用TrieDateField类型(一般范围查询)的查询应使用适当的日期语法:

  • timestamp:[* TO NOW]
  • createdate:[1976-03-06T23:59:59.999Z TO *]
  • createdate:[1995-12-31T23:59:59.999Z TO 2007-03-06T00:00:00Z]
  • 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]

原文链接:The Standard Query Parser
翻译:沉潜飞动
译文链接:solr查询 - 标准查询解析器