接着学习MultiTermQuery下的另一个Query子类FuzzyQuery,它用于模糊相似度查询,那这里说的相似度是如何判定的?用到的是Damerau-Levenshtein算法,具体这个算法的原理我也不是很清楚,只知道个大概,Levenshtein中文一般翻译为编辑距,何为编辑距?即两个字符串有一个转变成另一个所需要的最小的操作步骤,这里说的操作步骤指的是插入一个字符或修改一个字符或者删除一个字符。比如:
shade / shadow
他们的编辑距就是2,这个不用解释的吧。理解了编辑距就可以了,至于算法怎么实现的,自己去网上搜索Damerau-Levenshtein算法的Java实现。
首先还是要看看官方API对FuzzyQuery是怎么描述的:
一些重点我用红色框框标注出来了,大意就是FuzzyQuery的相似度计算使用的Damerau-Levenshtein,FuzzyQuery的transpositions属性设置为false表示启用Damerau-Levenshtein来计算相似度的,而默认该算法是不启用的,如图:
然后指出了FuzzyQuery的最大编辑距最大为2,这意味着什么?即如果编辑距大于2,FuzzyQuery会直接抛异常的,还是拿源码说话吧,如图:
public FuzzyQuery(Term term, int maxEdits, int prefixLength, int maxExpansions, boolean transpositions) { super(term.field()); if (maxEdits < 0 || maxEdits > LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE) { throw new IllegalArgumentException("maxEdits must be between 0 and " + LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE); } if (prefixLength < 0) { throw new IllegalArgumentException("prefixLength cannot be negative."); } if (maxExpansions <= 0) { throw new IllegalArgumentException("maxExpansions must be positive."); }
第一个if分支里判断了maxEdits(最大编辑距)如果小于0或大于LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE这个常量,则抛出一个异常,那么LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE常量值是多少,请看源码,如图:
意思就是如果你用字母“abs”去搜索“absolutely”(两者编辑距为7),在构建FuzzyQuery实例对象的时候,如果你把maxEdits设置为2,肯定搜不出来这毫无疑问,可是如果把maxEdits设置为7,FuzzyQuery对象构造都通不过,默认只支持编辑距0~2的查询,特此提醒!官方提示:因为编辑距设置太大会返回很多不相关的内容,官方不推荐你这么做,如果你需要支持这种功能,官方建议你移步到spellCheck模块(拼写检查模块)。
创建FuzzyQuery对象依然是通过构造函数,这是构造函数源码,
public FuzzyQuery(Term term, int maxEdits, int prefixLength, int maxExpansions, boolean transpositions) { super(term.field()); if (maxEdits < 0 || maxEdits > LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE) { throw new IllegalArgumentException("maxEdits must be between 0 and " + LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE); } if (prefixLength < 0) { throw new IllegalArgumentException("prefixLength cannot be negative."); } if (maxExpansions <= 0) { throw new IllegalArgumentException("maxExpansions must be positive."); } this.term = term; this.maxEdits = maxEdits; this.prefixLength = prefixLength; this.transpositions = transpositions; this.maxExpansions = maxExpansions; setRewriteMethod(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(maxExpansions)); }
prefixLength:就是表示指定长度的前缀会被认为是100%相似,举个例子说明会比较形象点,比如你文档里有个xiaopingguo字符,你拿“xiapngguo”去匹配,这时我们知道他们的编辑距为2,具体步骤就是ap之间插入一个字母o,pn之间插入一个字母i,所以编辑距为2,那prefixLength起什么作用呢?假如我们把prefixLength设置为4,即表示从第一个字符算起,xiap这4个字符跟xiaopingguo的前4个字符是100%相似的,即不能改变xiap这前4个字符,即在ap之间插入一个字母o是不允许的,这样就会导致相似度匹配失败,而如果我们把prefixLength设置为3就不会有问题,这就是prefixLength的作用,如果你确定两个字符有相同的前缀,就可以指定prefixLeng,如果设置不当会导致匹配失败,默认prefixLength是等于零的,即表示默认对prefixLength不做限制,可以对任意字符进行插入删除修改操作,但设置prefixLength长度可以加快匹配速度,因为你已经告诉了FuzzyQuery前N个字符是完全相同的,自然查询速度加快了,所以prefixLength该怎么设置,你们应该懂了。。
还有一个maxExpansions属性需要解释下,这个属性是用来设置在指定编辑距之内的所有Term的最大容量是多大,因为这些Term最终是要放入一个优先级队列(PriorityQueue)中的,然后通过BooleanQuery拼接成条件的,而BooleanQuery能拼接的条件个数是有限制的,所以弄个maxExpansions最大值设置,默认值是50,一般默认值就可以了,除非出现了too many boolean clause异常时你才需要适当调大这个值。
最后一个transpositions用来开关是否启用Damerau-Levenshtein算法的,前面提到过了,就不在多说了。
另外FuzzyQuery还提供很多构造函数重载,使用重载的构造函数时,需要对我刚提到的那几个参数的默认值了然于胸,如果默认值不符合你的要求,请更换构造函数。
Ok,该说的都说完了,我想大家应该对于怎么使用FuzzyQuery心里有底了,下面还是惯例提供一个使用示例代码:
String directoryPath = "D:/lucenedir"; String fieldName = "contents"; String queryString = "xiapngguo"; Query query = new FuzzyQuery(new Term(fieldName,queryString),2,3,50,false);
如果你还有什么问题请加我Q-Q:7-3-6-0-3-1-3-0-5,
或者加裙
一起交流学习!
相关推荐
源码分析方面,`FuzzyQuery`类在Lucene的`org.apache.lucene.search`包下,其内部实现了模糊匹配的逻辑。`defaultMinSimilarity`和`defaultPrefixLength`是预设的默认值,可以根据实际应用的需求进行调整。此外,`...
本项目"基于FuzzyQuery Lucene库的信息检索系统,Java实现"就是这样一个系统,它利用了Apache Lucene这一强大的全文搜索引擎库,提供了对模糊查询的支持。 Apache Lucene 是一个开源的Java库,用于构建高效、可扩展...
1. **FuzzyQuery**:通过设置模糊度参数`fuzziness`,如`new FuzzyQuery(new Term("field", "keyword"), Fuzziness.AUTO)`,允许查询词与索引词之间有一定的编辑距离。 2. **WildcardQuery**:使用通配符`?`(代表...
- **模糊查询**:`FuzzyQuery`允许搜索近似匹配的词。 #### 3.3 QueryParser - 自动生成`Query`对象,支持多种匹配模式(AND、OR、NOT等)。 ### 第四章 分词基础 #### 4.1 分词效果 - 分别展示英文和中文分词...
2. **模糊搜索**:支持通配符和近似搜索,例如 FuzzyQuery 可以处理拼写错误。 3. **评分与排序**:Lucene 使用 TF-IDF 算法计算文档的相关性分数,可以根据这些分数对结果进行排序。 4. **过滤器(Filter)**:...
近似搜索(Fuzzy Query)允许搜索类似但不完全相同的词汇。评分和排序可以根据相关性对结果进行排列,而命中高亮则可以突出显示文档中匹配的关键词。 ### 5. 示例代码 压缩包中的`SampleLuceneNet`可能包含一个...
**3.1.5 FuzzyQuery** - 允许一定程度的拼写错误。 **3.1.6 BooleanQuery** - 支持布尔逻辑操作,如 AND、OR。 **3.1.7 PhraseQuery** - 查询短语或固定顺序的词组。 **3.2 QueryParser** - `QueryParser` 类...
7. `FuzzyQuery`:模糊搜索,适用于拼写错误或近似词的查询。 8. `RegexQuery`:正则表达式查询,使用正则表达式进行模式匹配。 9. `SpanRegexQuery`:类似`RegexQuery`,但适用于`SpanQuery`子类,提供更高级的匹配...
Lucene的`FuzzyQuery`允许设置相似度阈值,从而返回近似匹配的结果。 #### 范围搜索 范围搜索允许用户基于数值或日期字段限定搜索范围。例如,搜索价格在100到200之间的商品,或者查询某个日期区间内的记录。 总之...
`FuzzyQuery`用于实现近似搜索,允许用户指定编辑距离。`WildcardQuery`和`PrefixQuery`则实现了通配符和前缀搜索。 为了提高搜索性能,Lucene引入了缓存机制。`Filter`类可以对查询结果进行过滤,如按日期范围筛选...
支持许多强大的查询类型,比如 PhraseQuery、WildcardQuery、RangeQuery、FuzzyQuery、BooleanQuery 等。 支持解析人们输入的丰富查询表达式。 允许用户使用定制排序、过滤和查询表达式解析扩展搜索行为。 使用基于...
3. **查询解析与执行**:用户输入的查询字符串会被解析成查询对象,Lucene提供多种查询类型,如布尔查询(BooleanQuery)、短语查询(PhraseQuery)和模糊查询(FuzzyQuery)。查询执行过程中,Lucene会根据倒排索引...
模糊搜索是通过`org.apache.lucene.search.FuzzyQuery`实现的,它可以计算查询词与文档中的词的Levenshtein距离,以确定匹配度。 2. **邻近搜索**(Proximity Searches): 使用`org.apache.lucene.search.spans....
2. **模糊搜索**:通过使用PrefixQuery、WildcardQuery或FuzzyQuery,可以实现模糊匹配和通配符查询。 3. **近似搜索**:通过使用SpanNearQuery或PhraseQuery,可以查找接近的词序。 4. **过滤器(Filter)**:...
这些功能通过`Highlighter`、`FuzzyQuery`、`PhraseQuery`等类实现,极大地扩展了搜索的实用性和精确度。 通过阅读和理解Lucene 2.4.0的源代码,开发者不仅可以掌握搜索引擎的基本原理,还能学习到如何在实际项目中...
4.9.3. 设置坡度值,支持FuzzyQuery 12 4.9.4. 设置通配符,支持WildcardQuery 12 4.9.5. 查找指定的Field 12 4.9.6. 范围的查找,支持RangeQuery 13 4.9.7. 现在还不支持SpanQuery 13 4.10. MultiFieldQueryParser类...
- **模糊查询(Fuzzy Query)**: 允许用户进行近似或拼写错误的查询。 ### 4. Lucene 7.2.1 版本的特性 - **性能优化**: 提升了索引和查询的速度,尤其是在大数据量场景下。 - **新的分析器**: 引入了新的语言...
同时,我们还将学习使用SpanQuery进行短语和近似匹配,以及使用FuzzyQuery处理拼写错误。 接下来,我们将关注Lucene的排序和评分机制。默认情况下,Lucene根据相关性对搜索结果进行排序,这涉及到TF-IDF算法。我们...
- **模糊查询 (Fuzzy Query)**:使用`~`符号进行模糊匹配,如`java~`或`java~0.8`,其中0.8表示编辑距离的最大值。 - **短语近似查询 (Proximity Query)**:`"大数据技术"~10`表示查找"大数据"与"技术"相距10个词...
通过使用SpanQuery和FuzzyQuery,我们可以实现这些高级查询。 4. **评分系统**:Lucene的TF-IDF(词频-逆文档频率)评分算法可以衡量文档的相关性。但在某些情况下,可能需要自定义评分函数,比如引入时间因素或者...