概述

尽管 Lucene 提供了通过其 API 创建自定义查询的功能,但它还通过查询解析器提供了一个丰富的查询语言,这是一个 lexer,它使用 JavaCC 将字符串解释为 Lucene 查询。

通常,查询解析器语法可能会在版本之间发生更改。本页面描述了当前版本的语法。如果您使用 Lucene 的不同版本,请查阅与您使用的版本一起分发的 docs/queryparsersyntax.html 的副本。

在选择使用提供的查询解析器之前,请考虑以下几点:

  • 如果您正在以编程方式生成查询字符串,然后使用查询解析器解析它,那么您应该认真考虑直接使用查询 API 构建查询。换句话说,查询解析器是为人工输入的文本而设计的,而不是为程序生成的文本。
  • 未标记的字段最好直接添加到查询中,而不是通过查询解析器添加。如果字段的值是由应用程序以编程方式生成的,则应为该字段生成查询子句。查询解析器使用的分析器旨在将人工输入的文本转换为词项。程序生成的值,如日期、关键字等,应该是一致的程序生成。
  • 在查询表单中,应使用查询解析器的字段应为通用文本的字段。其他字段,如日期范围、关键字等,最好直接通过查询 API 添加。具有一组可以在下拉菜单中指定的有限值的字段不应添加到随后解析的查询字符串中,而应该作为 TermQuery 子句添加。

术语

一个查询被分解为术语和运算符。有两种类型的术语:单个术语和短语。

  • 单个术语 是单个单词,例如 “test” 或 “hello”。
  • 短语 是由双引号括起来的一组单词,例如 “hello dolly”。

多个术语可以使用布尔运算符组合在一起,形成一个更复杂的查询(见下文)。

注意:用于创建索引的分析器将用于查询字符串中的术语和短语。因此,选择一个不会干扰查询字符串中使用的术语的分析器非常重要。

字段

Lucene 支持带字段的数据。在执行搜索时,您可以指定字段,或使用默认字段。字段名称和默认字段是特定于实现的。

您可以通过键入字段名,后跟冒号 “:”,然后是您要查找的术语,搜索任何字段。

例如,假设 Lucene 索引包含两个字段,title 和 text,而 text 是默认字段。如果要查找标题为 “The Right Way” 且包含文本 “don’t go this way” 的文档,可以输入:

title:"The Right Way" AND text:go

或者

title:"The Right Way" AND go

由于 text 是默认字段,因此不需要字段指示符。

注意:字段仅对其直接前面的术语有效,因此查询

title:The Right Way

将只在 title 字段中找到 “The”。它将在默认字段中(在本例中为 text 字段)找到 “Right” 和 “Way”。

术语修饰符

Lucene 支持修改查询术语以提供广泛的搜索选项。

通配符搜索

Lucene 支持在单个术语内进行单个字符和多个字符通配符搜索(不适用于短语查询)。

  • 要执行单个字符通配符搜索,请使用 “?” 符号。
  • 要执行多个字符通配符搜索,请使用 “*” 符号。

单个字符通配符搜索查找与替换为单个字符的术语匹配的术语。例如,要搜索 “text” 或 “test”,可以使用以下搜索:

te?t

多个字符通配符搜索查找 0 个或多个字符。例如,要搜索 test、tests 或 tester,可以使用以下搜索:

test*

您还可以在术语的中间使用通配符搜索。

te*t

注意:不能将 * 或 ? 符号用作搜索的第一个字符。

正则表达式搜索

Lucene 支持基于正斜杠 “/” 之间的模式的正则表达式搜索。语法可能会在不同版本中发生更改,但当前支持的语法在 RegExp 类中有记录。例如,要查找包含 “moat” 或 “boat” 的文档:

/[mb]oat/

模糊搜索

Lucene 支持基于 Damerau-Levenshtein 距离的模糊搜索。要进行模糊搜索,请在单个词术语的末尾使用波浪线 “~” 符号。例如,要搜索拼写类似于 “roam” 的词,请使用模糊搜索:

roam~

此搜索将找到类似于 foam 和 roams 的术语。

还可以使用一个额外(可选)的参数来指定允许的最大编辑次数。该值介于 0 和 2 之间,例如:

roam~1

如果未给出参数,则使用的默认值是 2 个编辑距离。

以前,此处允许使用浮点值。此语法被视为已弃用,将在 Lucene 5.0 中删除。

接近搜索

Lucene 支持查找在特定距离内的单词。要进行接近搜索,请在短语的末尾使用波浪线 “~” 符号。例如,要在文档中查找相距不超过 10 个单词的 “apache” 和 “jakarta”,请使用以下搜索:

"jakarta apache"~10

范围搜索

范围查询允许匹配字段值在由范围查询指定的下限和上限之间的文档。范围查询可以包括或不包括上限和下限。排序按字典顺序进行。

mod_date:[20020101 TO 20030101]

这将找到其 mod_date 字段的值在 20020101 和 20030101 之间(含)的文档。请注意,范围查询不仅限于日期字段。您还可以在非日期字段上使用范围查询:

title:{Aida TO Carmen}

这将找到所有标题在 Aida 和 Carmen 之间的文档,但不包括 Aida 和 Carmen。

包含上限和下限的范围查询由方括号表示。不包含上限和下限的范围查询由花括号表示。

提升术语

Lucene 根据找到的术语提供匹配文档的相关性级别。要提升术语,请在搜索的术语末尾使用插入符号 “^”,后跟术语旁边的提升因子(数字)。提升因子越高,术语将更相关。

提升允许您通过提升其术语来控制文档的相关性。例如,如果您正在搜索

jakarta apache

并且您希望术语 “jakarta” 更相关,请使用插入符号以及术语旁边的提升因子。您可以键入:

jakarta^4 apache

这将使包含术语 jakarta 的文档显得更相关。您还可以提升短语术语,例如:

"jakarta apache"^4 "Apache Lucene"

默认情况下,提升因子为 1。虽然提升因子必须是正数,但它可以小于 1(例如,0.2)。

布尔运算符

布尔运算符允许通过逻辑运算符组合术语。Lucene 支持 AND、+、OR、NOT 和 - 作为布尔运算符(注意:布尔运算符必须全部大写)。

OR 运算符

OR 运算符是默认的连接运算符。这意味着如果两个术语之间没有布尔运算符,则使用 OR 运算符。OR 运算符连接两个术语,如果两个术语中的任一个存在于文档中,则找到匹配的文档。这等同于使用集合的并集。符号   可以替代单词 OR。

要搜索包含 “jakarta apache” 或仅 “jakarta” 的文档,请使用以下查询:

"jakarta apache" jakarta

"jakarta apache" OR jakarta

AND 运算符

AND 运算符匹配包含单个文档文本中的两个术语的文档。这等同于使用集合的交集。符号 && 可以替代单词 AND。

要搜索包含 “jakarta apache” 和 “Apache Lucene” 的文档,请使用以下查询:

"jakarta apache" AND "Apache Lucene"

+(必须)运算符

”+” 或必须运算符要求在单个文档的字段中 “+” 符号之后的术语存在。

要搜索必须包含 “jakarta” 且可以包含 “lucene” 的文档,请使用以下查询:

+jakarta lucene

NOT 运算符

NOT 运算符排除包含 NOT 之后的术语的文档。这相当于使用集合的差异。符号 ! 可以替代单词 NOT。

要搜索包含 “jakarta apache” 但不包含 “Apache Lucene” 的文档,请使用以下查询:

"jakarta apache" NOT "Apache Lucene"

注意:NOT 运算符不能仅用于一个术语。例如,以下搜索将返回零结果:

NOT "jakarta apache"

-(禁止)运算符

”-“ 或禁止运算符排除包含 “-“ 符号之后的术语的文档。

要搜索包含 “jakarta apache” 但不包含 “Apache Lucene” 的文档,请使用以下查询:

"jakarta apache" -"Apache Lucene"

分组

Lucene 支持使用括号来对子句进行分组以形成子查询。如果您想要控制查询的布尔逻辑,这可能非常有用。

要搜索包含 “jakarta” 或 “apache” 且包含 “website” 的文档,请使用以下查询:

(jakarta OR apache) AND website

这消除了任何混淆,并确保 “website” 必须存在,而 “jakarta” 或 “apache” 中的任一术语可以存在。

字段分组

Lucene 支持使用括号将多个子句分组到单个字段。

要搜索标题包含单词 “return” 和短语 “pink panther” 的文档,请使用以下查询:

title:(+return +"pink panther")

转义特殊字符

Lucene 支持转义查询语法中的特殊字符。当前的特殊字符列表包括:

+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /

要转义这些字符,请在字符之前使用反斜杠 \。例如,要搜索 (1+1):2,请使用以下查询:

\(1\+1\)\:2

参考资料

https://lucene.apache.org/core/9_9_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description