`
lxwt909
  • 浏览: 570762 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Lucene5学习之QueryParser-Query解析器

阅读更多

    Lucene已经给我们提供了很多Query查询器,如PhraseQuery,SpanQuery,那为什么还要提供QueryParser呢?或者说设计QueryParser的目的是什么?QueryParser的目的就是让你从众多的Query实现类中脱离出来,因为Query实现类太多了,你有时候会茫然了,我到底该使用哪个Query实现类来完成我的查询需求呢,所以Lucene制定了一套Query语法,根据你传入的Query语法字符串帮你把它转换成Query对象,你不用关心底层是使用什么Query实现类。

      上面既然说到PhraseQuery和SpanQuery,那我就随带扯一扯这两个Query的区别吧,我估计这是很多初学Lucene者比较困惑的问题,两个Query都能根据多个Term进行查询,但PhraseQuery只能按照查询短语在文档中出现的顺序进行匹配,而不能颠倒过来匹配,比如你查询quick lazy,而索引中出现的是xxxxxxxxlazy qucikxxxxxxx,那PhraseQuery就没法匹配到了,这时候你就只能使用SpanQuery了,SpanQuery的inorder参数允许你设置是否按照查询短语在文档中出现的顺序进行匹配,以及是否允许有重叠,什么叫是否允许重叠?举个例子说明,假如域的值是这样的:“jumps over extremely very lazy broxn dog”,而你的查询短语是“dog over”,因为索引中dog在over后面,而你提供的查询短语中dog却在over前面,这与它在索引文档中出现的顺序是颠倒的,这时候你就不能使用PhraseQuery,PhraseQuery只能按出现顺序匹配,这种颠倒顺序匹配无法用PhraseQuery实现,把SpanQuery的inOrder设为false,就可以无视顺序了,即只要你能按slop规定的步数内匹配到dog over或者 over dog都算匹配成功。而如果inOrder设为true,意思就是你只能在规定步数内匹配到dog over,而匹配到over dog不算,并且匹配过程中不能有重叠。什么叫重叠?要得到dog over,那只能把over往右移动6步,可是它跨过了dog了,即dog重叠了,意思就是你只能在两者之间移动,不能跨越两者的边界进行匹配。我解释的不知道你们能看的明白不?注意两者的slop都是最多需要移动几步的意思即在规定步数内达到你想要的情况。

    跑题扯了半天PhraseQuery和SpanQuery的区别,回归正题,接着说说QueryParser的查询语法,关于QueryParser的语法,我们还是去看Lucene的官方Wiki吧,

https://lucene.apache.org/core/2_9_4/queryparsersyntax.html

 

Overview

Although Lucene provides the ability to create your own queries through its API, it also provides a rich query language through the Query Parser, a lexer which interprets a string into a Lucene Query using JavaCC.

Generally, the query parser syntax may change from release to release. This page describes the syntax as of the current release. If you are using a different version of Lucene, please consult the copy of docs/queryparsersyntax.html that was distributed with the version you are using.

Before choosing to use the provided Query Parser, please consider the following:

If you are programmatically generating a query string and then parsing it with the query parser then you should seriously consider building your queries directly with the query API. In other words, the query parser is designed for human-entered text, not for program-generated text.
Untokenized fields are best added directly to queries, and not through the query parser. If a field's values are generated programmatically by the application, then so should query clauses for this field. An analyzer, which the query parser uses, is designed to convert human-entered text to terms. Program-generated values, like dates, keywords, etc., should be consistently program-generated.
In a query form, fields which are general text should use the query parser. All others, such as date ranges, keywords, etc. are better added directly through the query API. A field with a limit set of values, that can be specified with a pull-down menu should not be added to a query string which is subsequently parsed, but rather added as a TermQuery clause.

   概述里提到QueryParser是通过JavaCC把用户输入的String转换成Query对象,那什么是JavaCC?我找到一段官方的介绍:

 

   

Java Compiler Compiler tm (JavaCC tm) is the most popular parser generator for use with Java tm applications. A parser generator is a tool that reads a grammar specification and converts it to a Java program that can recognize matches to the grammar. In addition to the parser generator itself, JavaCC provides other standard capabilities related to parser generation such as tree building (via a tool called JJTree included with JavaCC), actions, debugging, etc.

   JavaCC就是一个非常流行的用Java写的解析器生成器。

 

   Before choosing to use the provided Query Parser, please consider the following:
  意思就是提醒我们在选择使用QueryParser之前请先仔细考虑下面3个问题。

  1.QueryParser是为用户输入文本而设计的而不是你应用程序生成的文本而设计的,什么意思?意思就是你要考虑最恶劣的情况,因为用户输入的文本是无法预知的,你不能试图去规范用户输入什么样格式的查询字符串,如果你正在准备这么做,请你还是去使用Query api 构建你的Query实现类吧。

  2.没有分词的域请直接使用Query API来构建你的Query实现类,因为QueryParser会使用分词器对用户输入的文本进行分词得到N个Term,然后再根据匹配的,这点你必须清楚。

  3.第3点里提示你在设计查询表单时,对应普通的文本框可以直接使用QueryParser,但像日期范围啊搜索关键字啊下拉框里选定某个值或多个值进行限定值时,请使用Query API去做。

 

  Term:
  Term直接用一个单词表示,如“hello” ,多个Term用空格分割,如“hello java”,

  

  Field:
  可以添加上域,域和Term字符串用冒号隔开,如
title:"The Right Way",查询多个域用or或者and连接,

  如title:"The Right Way" AND text:go

 

  Term字符串你还可以使用通配符进行模糊匹配,如title: ja*a  title:ja?a title:ja*等等

  你还可以使用~字符开启FuzzyQuery,如title:roam~ or title:roam~0.8
  相似度阀值取值范围是0-1之间,默认值是0.5,

  

  QueryParser语法表达式还支持开启PhraseQuery短语查询,如title:"jakarta apache"~10

  表示查询title域中包含jakarta和apache字符且jakarta在apache前面且jakarta与apache之间间隔距离在10个间距之内(即<=10)。

 

  当然也支持范围查询,title:[java to php],age[18 to 28]

 

  你也可以单独为某个Term设置权重,如title:java^4,默认权重都为1.

  

  Boolean Operators即boolean操作符即or和and,用来链接多个Term的,如果两个Term仅仅用空格隔开,则默认为or链接的,如title:java^5 and content:lucen*

 

  当然还有+ -字符,表示必须符合和必须不符合即排除的意思,如+jakarta lucene,但注意只有一个Term的时候,不能用NOT,比如NOT "jakarta apache"是不合法的。

  而这样就可以,"jakarta apache" -"Apache Lucene"表示必须包含jakarta apache,但不能包含Apache Lucene.

 

  当or and条件很复杂时,需要限制优先级时可以用()小括号对Term条件进行分组,如(jakarta OR apache) AND website

 

  当对某个域的限定值有多个可以用or/and进行链接,也可以用()写在一起,如title:(+return +"pink panther"),当然你也可以用and拆成title:return and title:"pink panther"

 

  Lucene中需要进行转义的特殊字符包括

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

 

  

  QueryParser使用示例如下:

QueryParser parser = new QueryParser(fieldName, new IKAnalyzer());
Query query = parser.parse(queryString);

  queryString即为上面解释的那些queryParser查询表达式。

 

  但QueryParser并不能完全代替Query API,它并不能实现所有Query实现类的功能,比如它不支持SpanQuery.

 

  上面说的都是在单个域中查询,当然要在多个域中查询你可以使用or/and进行拼接,如果要在多个域中进行查询,你除了用or/and拼接以外,多了另一种选择,它就是MultiFieldQueryParser.我想Google大家都用过,Google的搜索界面就为我们提供了一个搜索输入框,用户只需要输入搜索关键字即可,而不用关心我输入的搜索关键字接下来会在哪些域(Field)里去查找,可能底层我们的索引会建立title,content,category等各种域,会依次从这几个域中去匹配是否有符合用户输入的查询关键字,但这些对用户都是透明的,用户也没必要去了解这些,MultiFieldQueryParser就是用来解决这种多域查询问题的。

  

public MultiFieldQueryParser(String[] fields, Analyzer analyzer, Map<String,Float> boosts) {
    this(fields, analyzer);
    this.boosts = boosts;
  }

 这是MultiFieldQueryParser的构造函数,首先fields毫无疑问就是提供一个域名称数组即你需要在哪些域中进行查询,analyzer即分词器对象,用户输入的搜索关键字我们需要对其分词,为什么要分词?因为用户输入的搜索关键字可能是一句话,比如:我女朋友要跟我分手,我该怎么办,分词后可能得到的只有两个关键字就是女朋友和分手,其他都是停用词被剔除了。最后一个boosts参数是一个map对象,是用来设置每个域的权重加权值的,map的key就是域名称,value就是加权值。boosts参数可以不传入,你传入一个null也行,不传入即表示不进行特殊加权,则默认权重加权值都是1.

 

  OK,有关QueryParser的知识就说这么多了,打完收工!!!

 

    如果你还有什么问题请加我Q-Q:7-3-6-0-3-1-3-0-5,

或者加裙
一起交流学习!

  

 

  

1
0
分享到:
评论
2 楼 lxwt909 2015-04-05  
yimi88 写道
什么时候写点solr5.0的资料。膜拜

Lucene5系列写完下一步就是Solr5了。预计5月份开始吧。
1 楼 yimi88 2015-04-03  
什么时候写点solr5.0的资料。膜拜

相关推荐

    最新全文检索 lucene-5.2.1 入门经典实例

    5. **QueryParser**: - 处理用户输入的查询字符串,转化为Lucene可以理解的Query对象。 6. **Query**: - 表示用户查询的抽象类,例如TermQuery、BooleanQuery、PhraseQuery等。 7. **Searcher**: - 包括...

    lucene-3.0.2-dev-src

    Lucene的查询解析器如`QueryParser`将用户输入的查询字符串转换为内部的查询对象。`Query`接口及其子类代表不同的查询类型,如`TermQuery`、`BooleanQuery`等。查询执行由`IndexSearcher`完成,它根据索引来查找...

    Lucene.Net-1.9.1-004-27Nov06源码

    - 查询解析器(QueryParser):将用户输入的查询字符串转化为Lucene可以理解的查询对象。 - 搜索器(Searcher):执行查询,返回匹配的文档列表。包括IndexSearcher,用于在线搜索,以及MultiSearcher,用于同时...

    lucene-4.10.3源码

    `src/core/org/apache/lucene/queryparser`目录下,包含各种查询解析器,如`QueryParser`,用于将用户输入的查询语句转化为`Query`对象。 3. 搜索:`src/core/org/apache/lucene/search`目录下的代码实现了搜索算法...

    lucene源码---官网最新下载

    - **QueryParser**: 解析用户输入的查询字符串,将其转换为 Lucene 查询对象。 2. **索引过程** - **Document**: 文档是 Lucene 中的基本数据单元,包含了待搜索的信息。开发者可以添加 Field 对象到 Document 中...

    解释Lucene QueryParser.jj文件

    本文将深入剖析Lucene中的QueryParser.jj文件,这是一份重要的语法定义文件,用于构建查询解析器。 QueryParser.jj,全称为JavaCC(Java Compiler Compiler)语法文件,是Lucene用来解析用户输入的查询字符串并转化...

    基于Lucene的全文检索的Java实现.pdf

    解压缩后,将analysis\common目录中的lucene-analyzers-common-x-x-x.jar,core目录中的lucene-core-x-x-x.jar,highlighter目录中的lucene-highlighter-x-x-x.jar,query parser目录中的lucene-queryparser-x-x-x....

    Lucene-core-2.0.0

    - **QueryParser**: 解析用户的查询字符串,生成对应的Query对象。 - **Query**: 表示一个搜索请求,可以是简单的关键词,也可以是复杂的布尔表达式。 - **ScoreDoc**: 搜索结果的评分和文档编号,用于排序。 3....

    Lucene 7.2.1 官方jar包

    - **QueryParser**: 解析用户输入的查询字符串,并转化为内部查询对象。 - **Searcher**: 执行查询,返回匹配文档的集合。 ### 3. Lucene的查询机制 - **布尔查询(Boolean Query)**: 支持AND、OR、NOT等逻辑...

    lucene-5.5.3.zip

    - **查询解析器(QueryParser)**:支持更复杂的查询语法,如布尔运算符、短语查询、通配符查询等。 - **多字段搜索**:可以在多个字段上同时进行搜索,并通过权重设置来调整不同字段的重要性。 - **近实时搜索**...

    lucene4.10.3的api的chm合集

    `lucene-queryparser-4.10.3.CHM`则涵盖了查询解析器的相关API,包括标准查询解析器、简化的查询解析器和多字段查询解析器。这些解析器将用户输入的查询字符串转化为Lucene可以处理的查询对象,是构建用户友好搜索...

    lucene-4.0.0-src.zip 【Lucene 4.0.0源码包src , source】

    2. **查询(Query)与解析器(Parser)**:用户输入的查询字符串通过`QueryParser`转化为内部表示的查询对象。4.0.0版本的查询解析器进行了优化,能更好地处理复杂的布尔逻辑和短语查询。 3. **搜索(Search)**:`...

    Lucene的原理完整版pdf

    查询语句通过`QueryParser`解析成`Query`对象,然后`IndexSearcher`会找到与查询匹配的文档。 3. **评分(Scoring)**:Lucene使用TF-IDF算法来评估文档与查询的相关性,给出一个评分。评分高的文档在搜索结果中...

    lucene-in-action-clone:lucene-in-action 一书中源代码的克隆

    查询解析是另一个关键部分,它涉及QueryParser(查询解析器)和Query(查询)类。开发者可以使用这些工具将用户输入转换为Lucene能够理解的查询表达式。查询执行则通过IndexSearcher(索引搜索器)完成,它可以找到...

    Lucene-2.3.1 源代码阅读学习

    - **QueryParser**:解析用户输入的查询字符串,生成Query对象。 - **Query**:表示查询条件,包括布尔查询、短语查询、范围查询等多种类型。 - **Searcher**:执行查询,返回匹配的Document集合。 - **Scoring*...

    java全文搜索lucene-3.0.0-src+lib.zip

    - 查询解析器(QueryParser):将用户输入的查询字符串转换为查询对象。 2.2 工作流程 Lucene的工作流程主要包括索引创建、索引读取和搜索三个阶段: - 创建索引:使用Analyzer处理文档,生成Token流,然后通过...

    Lucene3.3.0学习Demo

    4. **查询解析**:用户输入的查询字符串通过QueryParser转换为内部的Query对象。QueryParser支持布尔运算符、通配符和短语查询等复杂查询表达式。 5. **搜索执行**:使用`IndexSearcher`执行查询,找到匹配的文档。...

    Lucene.net-4.8.0 -new Bate.rar

    5. **查询解析器(QueryParser)**:将用户的自然语言查询转化为Lucene可以理解的查询对象。 三、源码解析 Lucene.Net 4.8.0的源码结构复杂而有序,主要包括以下几个关键组件: - **Index**:实现索引的创建、...

    Lucene---全文检索(文档pdf/txt/office/html)

    - **QueryParser**: 解析用户的查询字符串,生成相应的 Query 对象。 - **Query**: 表示一个搜索请求,可以是简单的关键词,也可以是复杂的布尔表达式。 - **Analyzer**: 处理文本,生成 Token 流,用于索引和搜索。...

Global site tag (gtag.js) - Google Analytics