Elasticsearch 其后的搜索引擎 Lucene 的 QueryString 查询语法

陪她去流浪 桃子 2020年06月14日 阅读次数:4170

这篇文章介绍 Elasticsearch 背后的 Lucene 搜索引擎的 QueryString 查询语法。

语法参考自 Apache Lucene 官网文档(版本 8.3.0),非 Elasticsearch 官方文档

Elasticsearch 和 Lucene 的版本迭代都非常快,本文所描述的与官网可能有差异。

  • 本文并非完整的语法介绍
  • 本文不区分搜索(Search)与查询(Query)
  • 本人未完整测试所有这些语法

概念

QueryString,带语法的查询字符串, 就是输入到搜索编辑框中的那一整个字符串。

一个 QueryString 会被拆分成多个 Terms(即词条)和 运算符。 词条分两种:1. 单个的 Term(单词), 2. Phrase(词组)。

单个的 Term 就是一个单词(比如:hello)。词组就是用引号引起来的一组单词(比如:"hello world")。

Field 即字段。Lucene 中的文档(Document)是由若干字段构成的,简单说就是 Key-Value 对。

不指定字段名的默认查询

如果在查询的时候没有指定字段,则查询索引的默认字段。

比如有一个索引包含两个字段,“标题(title)”和“文本(text)”,并且“文本(text)”是默认字段。

当搜索“go”时,因为没有指定字段名,则查询的是默认字段,即“text”。

指定字段名的查询

当需要查询某个字段具有某值时,需要指定字段的名字。语法:字段名:查询内容

比如:title:Waytitle:"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”的字段。

完整的正则表达式语法详见:

模糊搜索

模糊搜索基于编辑距离。距离范围为012,默认为 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

标签:ElasticSearch · Lucene