【monner的一点小感想】
个人最近研究Lucene时候,发现其搜索语句的词法语法搞到挺复杂的。
其实搜索引擎作为普通大众的工具,更多的应该在其搜索的准确性和速度方面做功夫,
大多数人都是输入个关键字就完成了搜索,很少有人会采用极度复杂的搜索语句的。
lucene项目目前基本上已经成为了开源搜索引擎的事实上底层索引标准!而且其索引生成算法和索引文件(准确的说是
索引数据存储)的模式基本已经比较固定,且都是采用的理论上的所谓最佳算法,我看在目前基本框架不变的基础上,想带来全新的改观基本很难!也难怪lucene的版本虽然在不断更新,但是核心包的性能却是一直大同小异了。
提个问题:如果由你来主导lucene项目的进一步开发,你会从什么方面对lucene进行切入和改进呢?!
目前我个人看来,只所以lucene作为Apache的顶级项目,下面又陆陆续续分支裂变了很多子项目如nutch/solr..等等
我们就可以看出其中道理来,lucene核心并不是我们研究的主要方向,而且说真的其核心接口已经十分固定并很人性化,
就引入哪么几个对象就可以轻易实现调用lucene为我服务!我们更应该从外围入手,如何开发更精致灵巧的实用项目,充分发挥lucene-core这个基础包的利用价值!!!
比如参考nutch,做个小型网站搜索引擎
比如参考regain,做个个人桌面文档资料搜索
。。。。
其实类似的需求在如今数据暴涨爆炸的年代已经非常必要了!可是我发现如今软件界并没有认真开发出几个实用好用耐用,用了离开不了的个人文档数据管理软件(当然,所谓数据其实可以更广义一点,就是一切需要你用脑筋去记忆,花心思去整理去管理的电子数据)。
谁能给我推荐几个好用的个人电子数据管理软件???
【monner补充下相关知识】
如果您学过编译原理,那么应该不会对YACC和Lex之类的词法分析工具陌生
Lex 即 Lexical Analyzar。
Yacc即 Yet Another Compiler Compiler
lucene采用类似的JAVACC实现,下面摘录如下:
常见常规表达式语法和细节整理如下:
字符 |
含义 |
A-Z, 0-9, a-z |
构成了部分模式的字符和数字。 |
. |
匹配任意字符,除了 \n。 |
- |
用来指定范围。例如:A-Z 指从 A 到 Z 之间的所有字符。 |
[ ] |
一个字符集合。匹配括号内的 任意 字符。如果第一个字符是 ^ 那么它表示否定模式。例如: [abC] 匹配 a, b, 和 C中的任何一个。 |
* |
匹配 0个或者多个上述的模式。 |
+ |
匹配 1个或者多个上述模式。 |
? |
匹配 0个或1个上述模式。 |
$ |
作为模式的最后一个字符匹配一行的结尾。 |
{ } |
指出一个模式可能出现的次数。 例如: A{1,3} 表示 A 可能出现1次或3次。 |
\ |
用来转义元字符。同样用来覆盖字符在此表中定义的特殊意义,只取字符的本意。 |
^ |
否定。 |
| |
表达式间的逻辑或。 |
"<一些符号>" |
字符的字面含义。元字符具有。 |
/ |
向前匹配。如果在匹配的模版中的“/”后跟有后续表达式,只匹配模版中“/”前面的部分。如:如果输入 A01,那么在模版 A0/1 中的 A0 是匹配的。 |
( ) |
将一系列常规表达式分组。 |
常规表达式举例
常规表达式 |
含义 |
joke[rs] |
匹配 jokes 或 joker。 |
A{1,2}shis+ |
匹配 AAshis, Ashis, AAshi, Ashi。 |
(A[b-e])+ |
匹配在 A 出现位置后跟随的从 b 到 e 的所有字符中的 0 个或 1个。 |
Lex或者YACC 中的标记声明类似 C 中的变量名。每个标记都有一个相关的表达式
标记声明举例
标记 |
相关表达式 |
含义 |
数字(number) |
([0-9])+ |
1个或多个数字 |
字符(chars) |
[A-Za-z] |
任意字符 |
空格(blank) |
" " |
一个空格 |
字(word) |
(chars)+ |
1个或多个 chars |
变量(variable) |
(字符)+(数字)*(字符)*(数字)* |
|
lucene 的Token部分描述采用的是通用的 巴科斯范式(BNF, Backus Naur Form)
如果您想对词法分析有所深入的话,强烈建议您学习下BNF!!!
========================================================================
【摘录原文章】
Lucene的查询解析代码为QueryParser.jj,语法为JavaCC实现的LL():
以下是Token部分:
_NUM_CHAR::=["0"-"9"] //数字
_ESCAPED_CHAR::= "\\" [ "\\", "+", "-", "!", "(", ")", ":", "^", "[", "]", "\"", "{", "}", "~", "*", "?" ] > //特殊字符,
_TERM_START_CHAR ::=( ~[ " ", "\t", "\n", "\r", "+", "-", "!", "(", ")", ":", "^","[", "]", "\"", "{", "}", "~", "*", "?" ] //TERM的起始字符,除了列出的其它字符都可以
_TERM_CHAR::=( <_TERM_START_CHAR> | <_ESCAPED_CHAR> | "-" | "+" ) > //TERM可使用字符
_WHITESPACE::= ( " " | "\t" | "\n" | "\r") //空格和回车,
<DEFAULT> TOKEN:
AND::=("AND" | "&&")
OR::=("OR" | "||")
NOT::=("NOT" | "!")
PLUS::="+"
MINUS::="-"
LPAREN::="("
RPAREN::=")"
COLON::=":"
STAR::="*"
CARAT::="^" //后接Boost,原文<CARAT: "^" > : Boost,后面Boost说明什么没明白
QUOTED::="\"" (~["\""] | "\\\"")+ "\"" // 表示用"包起来的字符串,字符"开始,中间由不是"的符号或者连着的这两个符号\"组成,字符"结束,
TERM::=<_TERM_START_CHAR> (<_TERM_CHAR>)*
FUZZY_SLOP::="~" ( (<_NUM_CHAR>)+ ( "." (<_NUM_CHAR>)+ )? )? //字符~开始,而后是数字.Lucene支持模糊查询,例如"roam~"或"roam~0.8", The value is between 0 and 1,算法为the Levenshtein Distance, or Edit Distance algorithm
PREFIXTERM::=(<_TERM_START_CHAR> | "*") (<_TERM_CHAR>)* "*" > //模糊查找,表示以某某开头的查询, 字符表示为"something*",前缀允许模糊符号*,中间可有字符也可没有, 结尾必须是*
WILDTERM::=(<_TERM_START_CHAR> | [ "*", "?" ]) (<_TERM_CHAR> | ( [ "*", "?" ] ))* > //类似上面,但同时支持?字符,结尾可以是字符也可以是* ?。使用[]表示or关系时,不需要使用|,只要,号分割即可
RANGEIN_START::="[" //在RangeQuery中,[或{表示了是否包含边界条件本身, 用字符表示为"[begin TO end]" 或者"{begin TO end}",后接RangeIn
RANGEEX_START::="{" //同上,后接RangeEx
<Boost> TOKEN:
NUMBER::=(<_NUM_CHAR>)+ ( "." (<_NUM_CHAR>)+ )? //后接DEFAULT, 整数或小数
<RangeIn> TOKEN:
RANGEIN_TO::="TO"
RANGEIN_END::="]" //后接DEFAULT, RangIn的结束
RANGEIN_QUOTED::= "\"" (~["\""] | "\\\"")+ "\"" //同上述QUOTED,表示用"包起来的字符串,
RANGEIN_GOOP::= (~[ " ", "]" ])+ //1个或多个不是空格和]的符号,这样就能提取出[]中的内容
<RangeEx> TOKEN :
RANGEEX_TO::="TO">
RANGEEX_END::="}" //后接DEFAULT, RangeEx的结束
RANGEEX_QUOTED::="\"" (~["\""] | "\\\"")+ "\"" //同上述QUOTED,表示用"包起来的字符串,
RANGEEX_GOOP::=(~[ " ", "}" ])+ //1个或多个不是空格和]的符号,这样就能提取出[]中的内容
<DEFAULT, RangeIn, RangeEx> SKIP : {
< <_WHITESPACE>>
} //所有空格和回车被忽略
以下为解析部分
Conjunction::=[ <AND> { ret = CONJ_AND; } | <OR> { ret = CONJ_OR; } ] //连接
Modifiers::=[ <PLUS> { ret = MOD_REQ; } | <MINUS> { ret = MOD_NOT; } | <NOT> { ret = MOD_NOT; } ] //+ - !符号
Query::=Modifiers Clause (Conjunction Modifiers Clause)*
Clause::=[(<TERM> <COLON>|<STAR> <COLON>)] //btw:代码中LOOKAHEAD[2]表示使用LL(2)
(Term|<LPAREN> Query <RPAREN> (<CARAT> <NUMBER>)?) //子句. ???????这儿语法有点,仿佛允许 *:(*:dog)这样的语法,很奇怪
Term::=(
(<TERM>|<STAR>|<PREFIXTERM>|<WILDTERM>|<NUMBER>) [<FUZZY_SLOP>] [<CARAT><NUMBER>[<FUZZY_SLOP>]}
| ( <RANGEIN_START> (<RANGEIN_GOOP>|<RANGEIN_QUOTED>) [ <RANGEIN_TO> ] (<RANGEIN_GOOP>|<RANGEIN_QUOTED> <RANGEIN_END> ) [ <CARAT> boost=<NUMBER> ] //这儿看出range必须同时有两端,不能只有有一端
| ( <RANGEEX_START> <RANGEEX_GOOP>|<RANGEEX_QUOTED> [ <RANGEEX_TO> ] <RANGEEX_GOOP>|<RANGEEX_QUOTED> <RANGEEX_END> )[ <CARAT> boost=<NUMBER> ] //在RangeQuery中,[或{表示了是否包含边界条件本身, 用字符表示为"[begin TO end]" 或者"{begin TO end}",后接RangeIn
| <QUOTED> [ <FUZZY_SLOP> ] [ <CARAT> boost=<NUMBER> ] //被""包含的内容
分享到:
相关推荐
**Lucene查询语法详解** Apache Lucene是一款高性能、全文本搜索库,被广泛应用于各种搜索引擎的构建。在使用Lucene进行信息检索时,理解和掌握其查询语法至关重要。本篇文章将深入探讨Lucene的查询语法,帮助你更...
2. **正则表达式(regex)在Lucene中的应用** 3. **regexQuery详解** 4. **示例代码解析** 5. **索引创建与查询流程** 6. **正则表达式的语法** #### Lucene简介 Lucene是一个高性能、全功能的全文搜索引擎库。它为...
### Lucene查询语法详解 #### 一、Lucene概述 Lucene是一款高性能、全功能的文本搜索引擎库,被广泛应用于各种需要实现全文检索的应用场景之中。Lucene支持复杂的查询语法,能够灵活地处理多样化的查询需求,使得...
24 Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser(1)
Lucene中的SpanQuery和PhraseQuery详解 Lucene是一个功能强大的搜索引擎库,提供了多种查询方式,其中SpanQuery和PhraseQuery是两个重要的查询类型。本文将详细介绍SpanQuery和PhraseQuery的使用和区别。 一、...
在Lucene.NET中,为了支持中文分词,通常需要结合第三方分词器,如IK Analyzer、HanLP、jieba.NET等。这些分词器具备丰富的词汇库和优秀的分词算法,能有效地对中文文本进行拆分。 - **IK Analyzer**:是一个开源的...
2. **查询解析**:Lucene支持复杂的查询语法,能够解析用户输入的查询字符串,转化为可执行的查询计划,包括布尔逻辑操作(AND、OR、NOT)、短语查询、近似查询等。 3. **评分系统**:Lucene采用TF-IDF算法评估文档...
在Lucene中,我们可以通过`FuzzyQuery`类来实现这种功能。`FuzzyQuery`基于Levenshtein距离算法,该算法计算两个字符串之间的差异程度,用于衡量它们的相似性。 首先,我们需要了解如何创建一个`FuzzyQuery`。在`...
在信息检索和存储系统中,Lucene是一个开源的全文搜索引擎库,广泛应用于各种需要全文搜索功能的软件项目中。为了高效地处理和检索存储的词项(term),Lucene使用了FST(有限状态转换器,Finite State Transducer)...
来自“猎图网 www.richmap.cn”基于IKAnalyzer分词算法的准商业化Lucene中文分词器。 1. 正向全切分算法,42万汉字字符/每秒的处理能力(IBM ThinkPad 酷睿I 1.6G 1G内存 WinXP) 2. 对数量词、地名、路名的...
npm install lucene-query-string-builder --save 特征 创建术语字符串时转义lucene特殊字符 包含所有lucene用途的运算符 简单的lucene.builder函数,用于定义lucene查询构建器 用法 让我们看看如何使用Lucene查询...
除了使用QueryParser来解析复杂的搜索语法外,还可以通过组合多个Query来达到目的。下面是一个示例代码: ```java query query1 = new TermQuery(new Term(fieldvalue, "name1")); query query2 = new ...
分词器会根据语法规则和词汇库将句子拆分成单个词语,以便于搜索。 ### 5. 在留言项目中的应用 在描述中提到的Leave_msg_project可能是演示如何在留言系统中使用Lucene的例子。在这个项目中,可能会有以下功能: -...
lucene 3.0 API中文帮助,学习的人懂得的
一种典型的实现是,我们会根据用户设定的关键词或规则,在lucene或elasticsearch中匹配数据,并最终将数据推送给客户。这种实现方式,要求文本数据必须已经建立好索引,访问时,会带来大量的IO消耗。各种基于定时...
1. **Analyzer**: 分析器是Lucene中的核心组件之一,负责将输入的文本分解成可搜索的词项(tokens)。在3.0版本中,Lucene提供了多种预定义的Analyzer,如StandardAnalyzer,它们可以处理不同语言的文本。 2. **...
4. **查询构造(Query Parsing)**:Lucene.NET支持多种查询语法,包括布尔查询、短语查询、范围查询等。了解如何构造这些查询可以帮助你设计出更精确的搜索逻辑。 5. **搜索执行(Searching)**:使用`...
3. **自定义查询语言**:使用JavaCC,你可以创建一个解析器来处理自定义的查询语言,这种语言可能包含特殊操作符或语法,然后将这些查询转化为Lucene的Query对象进行执行。 4. **扩展Lucene**:JavaCC可以用于扩展...
赠送jar包:lucene-core-7.2.1.jar; 赠送原API文档:lucene-core-7.2.1-javadoc.jar; 赠送源代码:lucene-core-7.2.1-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.2.1.pom; 包含翻译后的API文档:lucene...
在 Lucene 中,查询可以通过 QueryParser 创建,它支持多种查询语法,如布尔查询、短语查询、范围查询等。一旦查询被解析,IndexSearcher 将遍历索引,找到匹配的文档,并使用评分机制来决定文档的相关性。TF-IDF...