这篇文章介绍 Elasticsearch 背后的 Lucene 搜索引擎的 QueryString 查询语法。
语法参考自 Apache Lucene 官网文档(版本 8.3.0),非 Elasticsearch 官方文档。
Elasticsearch 和 Lucene 的版本迭代都非常快,本文所描述的与官网可能有差异。
- 本文并非完整的语法介绍
- 本文不区分搜索(Search)与查询(Query)
- 本人未完整测试所有这些语法
概念
QueryString
,带语法的查询字符串, 就是输入到搜索编辑框中的那一整个字符串。
一个 QueryString
会被拆分成多个 Term
s(即词条)和 运算符。
词条分两种:1. 单个的 Term(单词), 2. Phrase(词组)。
单个的 Term 就是一个单词(比如:hello)。词组就是用引号引起来的一组单词(比如:"hello world")。
Field
即字段。Lucene 中的文档(Document)是由若干字段构成的,简单说就是 Key-Value 对。
不指定字段名的默认查询
如果在查询的时候没有指定字段,则查询索引的默认字段。
比如有一个索引包含两个字段,“标题(title)”和“文本(text)”,并且“文本(text)”是默认字段。
当搜索“go”时,因为没有指定字段名,则查询的是默认字段,即“text”。
指定字段名的查询
当需要查询某个字段具有某值时,需要指定字段的名字。语法:字段名:查询内容
。
比如:title:Way
或 title:"The Right Way"
。
注意第 2 个例子中的引号,因为查询的是一个词组,中间有空格,应该用引号引起来。
而如果忘记了加引号写成title:The Right Way
,则语义是:仅在“title”中查找“The”,在默认字段(本文的“text”)中查找“Right” 或 “Way”。
通配符搜索
Lucene 支持在查询单词(不支持词组)的时候使用通配符查询。
单个字符的通配符用?
表示,多个(包含 0 个)字符的通配符用*
表示。
比如要查询“test”或“text”,则可以查询te?t
。要查询“test”,“tests”或“tester”,则可以查询test*
,或 te*t
。
注意:通配符不能出现在查询内容的最开始。
比如:*est
是错误的查询语法。
正则表达式搜索
正则表达式应该放在两个“/”之间。
比如:/[mb]oat/
查询包含“moat"或"boat”的字段。
完整的正则表达式语法详见:
模糊搜索
模糊搜索基于编辑距离。距离范围为0
、1
、2
,默认为 2。
在被搜索的单词(不支持词组)后面加上一个~
即可。
比如:roam~
,这将搜索到类似"foam”或“roams”的单词。
也可以手动指定编辑距离,语法:在 ~
后面再加上 距离 即可。
比如:roam~1
。
邻近搜索(Proximity Searches)
用于搜索单词间的距离不超过指定数值的词组。
语法:词组~距离
。
比如:"jakarta apache"~10
,用于查找“jakarta”和“apache”间的距离不超过 10 的文档。
范围搜索
用于查询某字段在某个指定范围内的文档。
范围可以是数值范围,也可以是字母范围。排序按字典序进行。
范围可以是开区间,也可以是闭区间。
语法:字段:[A TO B]
(闭区间,方括号) 或 字段:{C TO D}
(开区间,花括号,非数学上的小括号)。
比如:date:[20020101 TO 20030101]
或 title:{Aida TO Carmen}
。
提升某个词条的评分权重因子
词条评分越高,出现该词条文档的相关性就越高。有关评分算法,详见:Classic Scoring Formula。
语法:词条^因子
。
默认的因子是 1。因此,所以大家的权重一样。
当搜索jakarta apache
时(此时两个单词权重一样),如果 jakarta
更重要,则可以提升它的权重:jakarta^4 apache
。
词组也可以被提升:"jakarta apache"^4 "Apache Lucene"
。
布尔运算符
布尔运算符用于用布尔逻辑组合/连接多个查询条件。
Lucene 支持的布尔运算符:AND
或&&
、+
、OR
或||
、NOT
或!
、-
。
注意:
- 布尔运算符中的字母必须全部大写;
- 二元运算符(
AND
&&
OR
||
)与查询条件之间需要用空格隔开; - 一元运算符(
+
!
-
)与查询条件之间不能用空格隔开。
OR
OR
或||
, 是默认的连接运算符,可以省略。用 OR
连接的两个查询条件,只要满足其中一个即可。相当于求并集。
比如,要查询包含词组jakarta apache
或仅包含单词jakarta
的文档:"jakarta apache" jakarta
,或 "jakarta apache" OR jakarta
,或 "jakarta apache" || jakarta
。
AND
AND
或 &&
,用于连接两个查询条件,需要这两个条件同时满足。相当于求交集。
比如,查询包含jakarta apache
且包含 Apache Lucene
的文档:"jakarta apache" AND "Apache Lucene"
。
+
+
表示紧跟其后的词条必须出现。
比如:查询一定包含jakarta
但可能包含lucene
的文档:+jakarta lucene
。
NOT
NOT
或!
表示紧跟其后的词条一定不能出现。相当于求差集。
比如,要查询包含jakarta apache
但不包含Apache Lucene
的文档:"jakarta apache" NOT "Apache Lucene"
。
注意:NOT
不能单独使用!
形如 NOT "jakarta apache"
是错误的,将不会返回任何结果。
-
与 NOT
类似。
分组
分组用于构造子查询。用小括号表示。主要用于控制布尔逻辑查询的逻辑。
比如,要查询出现“jakarta”或“apache”(其一或两者都),且出现“website”的文档:(jakarta OR apache) AND website
。
字段查询的分组
比如:title:(+return +"pink panther")
。
特殊字符的转义
很多的标点符号有特殊意义,为了搜索这些符号本身,它们应该被转义。
当前版本的特殊字符有:+
-
&&
||
!
(
)
{
}
[
]
^
"
~
*
?
:
\
/
。
转义的方式是在每个这些字符的前面加上“\”符号。
比如要搜索“(1+1):2”,则应该输入\(1\+1\)\:2
。