参考文档:
Lucene查询语法
1. 什么是 Lucene
Lucene 是 apache 软件基金会的一个项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
2. 全文搜索
我们应用中的数据总体分为两种:结构化数据和非结构化数据。
2.1 结构化数据
指具有固定格式或有限长度的数据,如数据库,元数据等。
对于结构化数据查询,使用数据库搜索,数据库中的搜索很容易实现,通常都是使用sql语句进行查询,而且能很快的得到查询结果。
为什么数据库搜索很容易?因为数据库中的数据存储是有规律的,有行有列而且数据格式、数据长度都是固定的。
2.2 非结构化数据
指不定长或无固定格式的数据,如邮件,word 文档等磁盘上的文件
非结构化数据查询方法包括以下两种方法:
-
顺序扫描法(Serial Scanning)
所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。如利用 windows 的搜索也可以搜索文件内容,只是相当的慢。
-
全文检索(Full-text Search)
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
例如:字典。字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找一个字只能顺序扫描。然而字的某些信息可以提取出来进行结构化处理,比如读音,就比较结构化,分声母和韵母,分别只有几种可以一一列举,于是将读音拿出来按一定的顺序排列,每一项读音都指向此字的详细解释的页数。我们搜索时按结构化的拼音搜到读音,然后按其指向的页数,便可找到我们的非结构化数据——也即对字的解释。
这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。
3. Lucene实现全文检索流程
上图是Lucene实现全文检索的大致流程,也可参考:全文检索流程
- 绿色部分表示索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
确定原始内容即要搜索的内容→采集文档→创建文档→分析文档→索引文档 - 红色部分表示搜索过程,从索引库中搜索内容,搜索过程包括:
用户通过搜索界面→创建查询→执行搜索,从索引库搜索→渲染搜索结果
4. Lucene 查询语法
可参考
https://developer.aliyun.com/article/65561
http://lucene.apache.org/java/3_0_1/queryparsersyntax.html
4.1 语法关键字
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /
如果所要查询的查询词中本身包含关键字,则需要用\进行转义。
4.2. 查询词(Term)
Lucene 支持两种查询词,一种是单词,如 "hello",一种是词组(phrase),如 "hello world"。
title: hello
表示查询在 title 域中含有 hello 单词的文档。
title: "hello world"
表示查询在 title 域中含有 hello world 词组的文档。
title:(hello world)
表示查询在 title 域中含有 hello 与 world 单词的文档。
4.3 查询域(Field)
在查询语句中,可以指定从哪个域中寻找查询词,如果不指定,则从默认域中查找。
查询域和查询词之间用:分隔,如title:"Do it right"。
:仅对紧跟其后的查询词起作用,如果title:Do it right,则仅表示在title中查询Do,而it right要在默认域中查询。
4.4 通配符查询(Wildcard)
支持两种通配符:?表示一个字符,*表示多个字符。
通配符可以出现在查询词的中间或者末尾,如te?t,test*,tet,但决不能出现在开始,如test,?test。
4.5 模糊查询(Fuzzy)
模糊查询的算法是基于 Levenshtein Distance,也即当两个词的差别小于某个比例的时候,就算匹配,如 roam~0.8
,即表示差别小于0.2,相似度大于 0.8 才算匹配。
4.6 临近查询(Proximity)
在词组后面跟随~10,表示词组中的多个词之间的距离之和不超过10,则满足查询。
所谓词之间的距离,即查询词组中词为满足和目标词组相同的最小移动次数。
如索引中有词组"apple boy cat"。
如果查询词为"apple boy cat"~0,则匹配。
如果查询词为"boy apple cat"~2,距离设为2方能匹配,设为1则不能匹配。
(0) | boy | apple | cat |
---|---|---|---|
(1) | boyapple | cat | |
(2) | apple | boy | cat |
如果查询词为"cat boy apple"~4,距离设为4方能匹配。
(0) | cat | boy | apple |
---|---|---|---|
(1) | catboy | apple | |
(2) | boy | catapple | |
(3) | boyapple | cat | |
(4) | apple | boy | cat |
4.7 区间查询(Range)
区间查询包含两种,一种是包含边界,用[A TO B]指定,一种是不包含边界,用指定。
如date:[20020101 TO 20030101],当然区间查询不仅仅用于时间,如title:
4.8 增加一个查询词的权重(Boost)
可以在查询词后面加^N来设定此查询词的权重,默认是1,如果N大于1,则说明此查询词更重要,如果N小于1,则说明此查询词更不重要。
如jakarta4 apache,"jakarta apache"4 "Apache Lucene"
4.9 布尔操作符
布尔操作符包括连接符,如AND,OR,和修饰符,如NOT,+,-。
默认状态下,空格被认为是OR的关系,QueryParser.setDefaultOperator(Operator.AND)设置为空格为AND。
+表示一个查询语句是必须满足的(required),NOT和-表示一个查询语句是不能满足的(prohibited)。
4.10 组合
可以用括号,将查询语句进行组合,从而设定优先级。
如(jakarta OR apache) AND website