男女做暖暖试看网站,网站建设空间申请,企业网站建设首选智投未来1,wordpress历史版本下载地址lucene 查询示例本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要#xff0c;然后了解Lucene中搜索的工作方式。 此外#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中… lucene 查询示例 本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中您将了解Lucene。 您将了解为什么这样的库很重要然后了解Lucene中搜索的工作方式。 此外您将学习如何将Lucene Search集成到您自己的应用程序中以提供强大的搜索功能。 在这里查看 目录 1.引言 2.Lucene查询 3Lucene查询API 4基本搜索 4.1。条款 4.2。通配符查询 4.3。布尔运算符 4.3分组 4.4。短语查询 4.5。范围查询 4.6。前缀查询 4.7。模糊查询 1.引言 在上一章中我们了解了Lucene搜索引擎的不同组件 。 我们还使用lucene索引和搜索程序构建了一个小型搜索应用程序。 在本章中我们将讨论Lucene查询。 2.Lucene查询 Lucene具有用于查询其索引的自定义查询语法。 查询分为术语和运算符。 术语有两种类型 1 . 单词和2.短语 。 单个术语是一个单词例如“测试”或“样本”。 词组是一组用双引号括起来的单词例如“ welcome lucene”。 可以将多个术语与布尔运算符组合在一起以形成更复杂的查询。 对于Lucene JavaTermQuery是最原始的查询。 然后是BooleanQueryPhraseQuery和许多其他Query子类可供选择。 字段执行搜索时我们可以指定要搜索的字段。任何现有的字段名称都可以用作字段名称。 语法为FieldNameVALUE 。 有一些特殊的字段类型具有自己的语法来定义查询词。 例如DateTimeModificationDate2010-09-01 12:00:00我们将在后面的部分中解释对这些字段的搜索操作。 3Lucene查询API 当Lucene的QueryParser解析人类可读的查询时它将转换为Query类的单个具体子类。 我们需要对基础的具体Query子类有所了解。 下表列出了相关的子类它们的用途以及一些示例表达式 查询实施 目的 样本表达 TermQuery 单项查询实际上是一个单词。 雷诺 PhraseQuery 多个项的顺序匹配或彼此接近的匹配项 “前方点亮” RangeQuery 用开始和结束词之间包括或排除端点的词来匹配文档。 [A到Z] {A到Z} WildcardQuery 轻量级的类似于正则表达式的术语匹配语法。 j * v f ?? bar PrefixQuery 匹配以指定字符串开头的所有术语。 起司* FuzzyQuery Levenshtein紧密匹配算法。 树〜 BooleanQuery 将其他Query实例聚合为允许ANDOR和NOT逻辑的复杂表达式。 雷诺和“前方点亮” 奶酪*-奶酪 所有这些Query实现都在org.apache.lucene.search包中。 BooleanQuery是一种特殊情况因为它是一个聚合其他查询包括用于复杂表达式的嵌套BooleanQuery 的Query容器。 这是一个基于查询片段的BooleanQuery 。 在这里我们可以看到QueryParser创建的查询与API创建的查询等效 public class RulezTest extends TestCase { public void testJavaNotDotNet() throws Exception { BooleanQuery apiQuery new BooleanQuery(); apiQuery.add(new TermQuery(new Term(contents, java)), true, false); apiQuery.add(new TermQuery(new Term(contents, net)), true, false); apiQuery.add(new TermQuery(new Term(contents, dot)), false, true); Query qpQuery QueryParser.parse(java AND net NOT dot, contents, new StandardAnalyzer()); // Query and subclasses behave as expected with .equals assertEquals(qpQuery, apiQuery); }
} Query类的一些有趣的功能是它们的toString方法。 每个Query子类都会生成等效的QueryParserexpression 尽管不一定在文本上精确。 有两种变体一种是标准的Object.toString重写方法另一种接受默认字段名称。 下面的测试案例演示了这两种方法的工作原理并说明了如何返回等效但不是确切的表达式。 public void testToString() throws Exception { Query query QueryParser.parse(java AND net NOT dot, contents, new StandardAnalyzer()); assertEquals(java net -dot, query.toString(contents)); assertEquals(contents:java contents:net -contents:dot, query.toString());
} 注意解析的表达式是“ java AND net NOT dot”但是从toString方法返回的表达式使用了缩写语法“ java net -dot”。 我们的第一个测试用例 testJavaNotDotNet 证明了底层查询对象本身是等效的。 no-arg toString方法不对每个术语的字段名称做任何假设并使用字段选择器语法明确指定它们。 使用这些toString方法可方便地诊断QueryParser问题。 4基本搜索 在大多数情况下您要查找单个术语或短语即由双引号引起的一组单词“示例应用程序”。 在这些情况下我们将在默认索引数据中查找包含这些单词的内容这些默认索引数据包含内容的所有相关文本。 在更复杂的情况下我们可能需要根据要查找的内容的类型或位置进行某些过滤或者我们要在特定字段中进行搜索。 在这里我们可以学习如何构建更复杂的查询这些查询可用于有效地在大型存储库中查找内容。 4.1。条款 假设我们要在标签字段中使用关键字“博客”进行搜索。 语法将是 tag : blog 现在我们将在标签字段中搜索短语“ lucene blog”。 为此语法将是 tag : lucene blog 现在让我们在标签字段中搜索“ lucene blog”然后在正文中搜索“ technical blog” tag : lucene blog AND body : technical blog 假设我们要在标签字段中搜索短语“ lucene blog”在正文中搜索“技术博客”或者在标签字段中搜索“ searching blog” (tag : lucene blog AND body : technical blog) OR tag : searching blog 如果我们想在标签字段中搜索“博客”而不是“ lucene”则语法看起来会相似 tag : blog -tag : lucene4.2。通配符查询 Lucene支持在单个术语而不是短语查询中的单字符和多字符通配符搜索。 要执行单个字符通配符搜索请使用“” 符号。 要执行多字符通配符搜索请使用“ *”符号。 单字符通配符搜索将查找与替换了单个字符的词相匹配的术语。 例如要搜索“文本”或“测试”我们可以使用搜索tet 多字符通配符搜索将查找0个或多个字符。 例如要搜索测试测试或测试员我们可以使用搜索 test* 我们还可以在术语中间使用通配符搜索。 te*t 这是Lucene通配符搜索的示例 假设我们在“文件”目录中有两个文件。 test-foods.txt 以下是Deron喜欢的一些食物 hamburger french fries steak mushrooms artichokes sample-food.txt 以下是妮可喜欢的一些食物 apples bananas salad mushrooms cheese 现在我们看一下LuceneWildcardQueryDemo类。 此类基于上述文本文件通过createIndex()方法创建索引此后它尝试对该索引执行8个通配符搜索。 使用WildcardQuery类执行其中四个搜索而使用QueryParser类执行其他四个搜索。 首先使用createIndex()方法对以上两个文件建立索引。 public static void createIndex() throws CorruptIndexException, LockObtainFailedException, IOException {Analyzer analyzer new StandardAnalyzer();boolean recreateIndexIfExists true;IndexWriter indexWriter new IndexWriter(INDEX_DIRECTORY, analyzer, recreateIndexIfExists);File dir new File(FILES_TO_INDEX_DIRECTORY);File[] files dir.listFiles();for (File file : files) {Document document new Document();String path file.getCanonicalPath();document.add(new Field(FIELD_PATH, path, Field.Store.YES, Field.Index.UN_TOKENIZED));Reader reader new FileReader(file);document.add(new Field(FIELD_CONTENTS, reader));indexWriter.addDocument(document);}indexWriter.optimize();indexWriter.close();
} 为了使用查询解析器执行搜索操作我们可以添加一个名为searchIndexWithQueryParser()的方法 public static void searchIndexWithQueryParser(String whichField, String searchString) throws IOException,ParseException {System.out.println(\\nSearching for searchString using QueryParser);Directory directory FSDirectory.getDirectory(INDEX_DIRECTORY);IndexSearcher indexSearcher new IndexSearcher(directory);QueryParser queryParser new QueryParser(whichField, new StandardAnalyzer());Query query queryParser.parse(searchString);System.out.println(Type of query: query.getClass().getSimpleName());Hits hits indexSearcher.search(query);displayHits(hits);
} 使用以下代码在searchIndexWithWildcardQuery()方法中执行WildcardQuery查询 Directory directory FSDirectory.getDirectory(INDEX_DIRECTORY); IndexSearcher indexSearcher new IndexSearcher(directory); Term term new Term(whichField, searchString); Query query new WildcardQuery(term); Hits hits indexSearcher.search(query); QueryParser查询通过以下方式在searchIndexWithQueryParser()方法中执行 Directory directory FSDirectory.getDirectory(INDEX_DIRECTORY); IndexSearcher indexSearcher new IndexSearcher(directory); QueryParser queryParser new QueryParser(whichField, new StandardAnalyzer()); Query query queryParser.parse(searchString); Hits hits indexSearcher.search(query); 从我们的main方法可以看到 LuceneWildcardQueryDemo类执行八个通配符搜索 searchIndexWithWildcardQuery(FIELD_CONTENTS, t*t); searchIndexWithQueryParser(FIELD_CONTENTS, t*t); searchIndexWithWildcardQuery(FIELD_CONTENTS, sam*); searchIndexWithQueryParser(FIELD_CONTENTS, sam*); searchIndexWithWildcardQuery(FIELD_CONTENTS, te?t); searchIndexWithQueryParser(FIELD_CONTENTS, te?t); searchIndexWithWildcardQuery(FIELD_CONTENTS, *est); try { searchIndexWithQueryParser(FIELD_CONTENTS, *est); } catch (ParseException pe) { pe.printStackTrace(); } 最后我们将使用类似的方法打印每次搜索操作的命中数 public static void displayHits(Hits hits) throws CorruptIndexException, IOException {System.out.println(Number of hits: hits.length());IteratorHit it hits.iterator();while (it.hasNext()) {Hit hit it.next();Document document hit.getDocument();String path document.get(FIELD_PATH);System.out.println(Hit: path);}
} 如果我们运行上面的代码它将向我们显示 Searching for t*t using WildcardQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/test-foods.txtSearching for t*t using QueryParser
Type of query: WildcardQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/test-foods.txtSearching for sam* using WildcardQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/sample-foods.txtSearching for sam* using QueryParser
Type of query: PrefixQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/sample-foods.txtSearching for te?t using WildcardQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/test-foods.txtSearching for te?t using QueryParser
Type of query: WildcardQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/test-foods.txtSearching for *est using WildcardQuery
Number of hits: 1
Hit: /home/debarshi/workspace/Test/filesToIndex/test-foods.txtSearching for *est using QueryParserorg.apache.lucene.queryParser.ParseException: Cannot parse *est: * or ? not allowed as first character in WildcardQuery at org.apache.lucene.queryParser.QueryParser.parse(QueryParser.java:175) at LuceneWildcardQueryDemo.searchIndexWithQueryParser(LuceneWildcardQueryDemo.java:81) at LuceneWildcardQueryDemo.main(LuceneWildcardQueryDemo.java:46) 第一个查询使用带有“ t * t”的WildcardQuery对象。 由于“ t * t”与索引中的“ test”匹配因此此查询返回1次匹配。 第二个查询使用QueryParser查询“ t * t”。 QueryParser parse()方法返回WildcardQuery 并且该查询返回1个匹配项因为它与第一个查询基本相同。 第三个查询使用带有“ sam *”的WildcardQuery对象。 由于“ sam *”与“ sample”匹配因此该通配符查询获得了一次成功。 第四个查询使用带有“ sam *”的QueryParser 。 但是请注意QueryParser的parse()方法返回PrefixQuery而不是WildcardQuery 。 由于星号在“ sam *”的末尾。 由于“ sam *”与“ sample”匹配因此该针对“ sam *”的PrefixQuery命中。 第五个查询是WildcardQuery 它在其搜索词“ tet”中使用问号。 问号可以匹配一个字符。 由于“ tet”与“ test”匹配因此搜索返回1个匹配项。 第六个查询使用带有“ tet”的QueryParser 。 QueryParser parse()方法返回WildcardQuery 并且与第五个查询一样它获得成功。 第七个查询是“ * est”的WildcardQuery查询。 由于“ test”匹配“ * est”因此它收到一个匹配。 通常在第一个字符为通配符的情况下执行查询不是一个好主意。 第八个查询是“ * est”的QueryParser查询。 请注意 QueryParser对象甚至不允许我们执行第一个字符为星号的查询。 它抛出一个解析异常。 4.3。布尔运算符 布尔运算符允许通过逻辑运算符组合术语。 Lucene支持AND“ ”ORNOT和“-”作为布尔运算符注意布尔运算符必须为ALL CAPS。 OR运算符是默认的合取运算符。 这意味着如果两个术语之间没有布尔运算符则使用OR运算符。 OR运算符链接两个术语如果文档中存在两个术语中的任何一个则查找匹配的文档。 这等效于使用集的并集。 符号|| 可以代替单词OR。 要搜索包含“ jakarta apache”或仅包含“ jakarta”的文档请使用查询 jakarta apache jakarta 要么 jakarta apache OR 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 “-” “-”或禁止运算符排除包含在“-”符号后的术语的文档。 要搜索包含“ jakarta apache”但不包含“ Apache Lucene”的文档请使用以下查询 jakarta apache -Apache Lucene4.3分组 Lucene支持使用括号将子句分组以形成子查询。 如果要控制查询的布尔逻辑这可能非常有用。 要搜索“ jakarta”或“ apache”和“网站”请使用查询 (jakarta OR apache) AND website 这样可以消除任何混乱并确保您必须存在该网站并且可能存在“雅加达”或“ apache”一词。 现场分组 Lucene支持使用括号将多个子句分组到一个字段中。 要搜索包含单词“ return”和短语“ pink panther”的标题请使用以下查询 title:(return pink panther) 转义特殊字符 Lucene支持转义查询语法中包含的特殊字符。 当前列表的特殊字符为 – || {} [] ^”〜*吗 \ 要转义这些字符请在字符前使用“ \”反斜杠。 例如要搜索1 12请使用查询 \\(1\\1\\)\\:24.4。短语查询 Lucene中的PhraseQuery匹配包含特定术语序列的文档。 PhraseQuery使用存储在索引中的术语的位置信息。 查询短语中单词之间允许的其他单词的数量称为“斜率”。 可以通过调用setSlop方法进行设置。 如果为零则为精确短语搜索。 对于较大的值其工作方式类似于WITHIN或NEAR运算符。 斜率实际上是一个编辑距离其中单位对应于查询短语中词条移动的位置。 例如要切换两个单词的顺序需要两个步骤第一个步骤将单词彼此放在首位因此要允许对短语进行重新排序斜率必须至少为两个。 得分更高的比赛要比更差劲的比赛得分高因此搜索结果将按照准确性进行排序。 默认情况下斜率为零要求完全匹配。 PhraseQuery还支持多个术语短语。 短语查询可以与其他术语组合也可以与BooleanQuery组合使用。 默认情况下子句的最大数量限制为1,024。 在前面的Lucene通配符查询示例中我们已经基于两个文本文件完成了搜索操作。 现在我们将尝试在lucene中使用PhraseQuery查找匹配的短语。 为此我们将引入一个新方法searchIndexWithPhraseQuery()来代替searchIndexWithWildcardQuery()方法该方法采用两个字符串表示文档中的单词和searchIndexWithPhraseQuery()值。 它通过基于“ contents”字段以及string1和string2参数添加两个Term对象来构造PhraseQuery 。 然后它使用setSlop()方法设置PhraseQuery对象的setSlop()值。 通过将PhraseQuery对象传递给IndexSearcher的search()方法进行search() 。 这是代码 public static void searchIndexWithPhraseQuery(String string1, String string2, int slop) throws IOException,ParseException {Directory directory FSDirectory.getDirectory(INDEX_DIRECTORY);IndexSearcher indexSearcher new IndexSearcher(directory);Term term1 new Term(FIELD_CONTENTS, string1);Term term2 new Term(FIELD_CONTENTS, string2);PhraseQuery phraseQuery new PhraseQuery();phraseQuery.add(term1);phraseQuery.add(term2);phraseQuery.setSlop(slop);displayQuery(phraseQuery);Hits hits indexSearcher.search(phraseQuery);displayHits(hits);
} 而且我们从main()调用此方法 searchIndexWithPhraseQuery(french, fries, 0);searchIndexWithPhraseQuery(hamburger, steak, 0);searchIndexWithPhraseQuery(hamburger, steak, 1);searchIndexWithPhraseQuery(hamburger, steak, 2);searchIndexWithPhraseQuery(hamburger, steak, 3);searchIndexWithQueryParser(french fries); // BooleanQuerysearchIndexWithQueryParser(\\french fries\\); // PhaseQuerysearchIndexWithQueryParser(\\hamburger steak\\~1); // PhaseQuerysearchIndexWithQueryParser(\\hamburger steak\\~2); // PhaseQuery 第一个查询以斜率0搜索“ french”和“ fries”这意味着短语搜索最终是对“ french fries”的搜索其中“ french”和“ fries”彼此相邻。 由于这存在于test-foods.txt中因此我们获得了1次点击。 在第二个查询中我们搜索坡度为0的“汉堡”和“牛排”。由于在两个文档中“汉堡”和“牛排”都不相邻因此命中0。 第三个查询还涉及对“汉堡包”和“牛排”的搜索但斜率为1。这些单词彼此之间的距离不超过1个单词因此我们获得0次匹配。 第四个查询以“ 2”的斜率搜索“汉堡”和“牛排”。在test-foods.txt文件中我们有“……汉堡薯条……”字样。 由于“汉堡”和“牛排”彼此之间不超过两个字因此我们获得了1分。 第五个短语查询是相同的搜索但坡度为3。由于“汉堡包”和“牛排”彼此带有三个单词彼此是两个单词因此命中率为1。 接下来的四个查询使用QueryParser 。 注意在第一个QueryParser查询中我们得到一个BooleanQuery而不是PhraseQuery 。 这是因为我们传递了QueryParser的parse()方法“炸薯条”而不是“ \”炸薯条\””。 如果希望QueryParser生成PhraseQuery则搜索字符串需要用双引号引起来。 下一个查询确实搜索“ \”炸薯条\”我们可以看到它生成了一个PhraseQuery 默认PhraseQuery为0并响应该查询而获得1次PhraseQuery 。 最后两个QueryParser查询演示了设置倾斜值。 我们可以看到可以在搜索字符串的双引号后面设置斜率值并在其后加上斜线号〜和斜率号。 4.5。范围查询 与专有术语范围内的文档匹配的Query 。 它允许匹配字段值在RangeQuery指定的下限和上限之间的RangeQuery 。 范围查询可以包含上限也可以不包括上限和下限。 排序是按字典顺序进行的按字典顺序排列排序的项的集合。 现在如果要为Lucene搜索操作实现RangeQuery 则必须添加一个名为searchIndexWithRangeQuery() 该方法基本上是一个构造函数需要Term指示范围的开始 Term指示范围的结束和一个布尔值指示搜索是包含开始和结束值“ true”还是排除开始和结束值“ false”。 代码看起来像 public static void searchIndexWithRangeQuery(String whichField, String start, String end, boolean inclusive)throws IOException, ParseException {System.out.println(\\nSearching for range start to end using RangeQuery);Directory directory FSDirectory.getDirectory(INDEX_DIRECTORY);IndexSearcher indexSearcher new IndexSearcher(directory);Term startTerm new Term(whichField, start);Term endTerm new Term(whichField, end);Query query new RangeQuery(startTerm, endTerm, inclusive);Hits hits indexSearcher.search(query);displayHits(hits);
} 现在我们将调用上述方法 searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, 2014-04-01-00-00-00, 2014-04-01-23-59-59, INCLUSIVE);searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, 2014-04-02-00-00-00, 2014-04-02-23-59-59, INCLUSIVE);searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, 2014-04-01-00-00-00, 2014-04-01-21-21-02, INCLUSIVE);searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, 2014-04-01-00-00-00, 2014-04-01-21-21-02, EXCLUSIVE);// equivalent range searches using QueryParsersearchIndexWithQueryParser(FIELD_LAST_MODIFIED, [2014-04-01-00-00-00 TO 2014-04-01-23-59-59]);searchIndexWithQueryParser(FIELD_LAST_MODIFIED, [2014-04-02-00-00-00 TO 2014-04-02-23-59-59]);searchIndexWithQueryParser(FIELD_LAST_MODIFIED, [2014-04-01-00-00-00 TO 2014-04-01-21-21-02]);searchIndexWithQueryParser(FIELD_LAST_MODIFIED, {2014-04-01-00-00-00 TO 2014-04-01-21-21-02}); 最后 createIndex()方法稍有变化。 我们添加了一些实现日期时间的操作并打印了索引文件的最后修改时间。 在控制台输出的顶部我们可以看到两个文件都已建立索引并且这些文件的“最后修改”时间是“ 2014-04-01-21-21-02”对于test-foods.txt 和“ 2014-04-01-21-21-38”针对sample-foods.txt。 在第一个范围查询中我们搜索所有在2014年4月1日最后一次修改的文件。由于两个文件在该日期最后一次修改这将返回2次匹配。 在第二个范围查询中我们搜索所有在2014年4月2日最后一次修改的文件。由于两个文档都在2014年4月1日最后一次修改因此返回0次匹配。 接下来我们在2014年4月1日至2014年4月1日含2014年之间进行搜索。 由于test-foods.txt的上次修改时间为2014-04-01-21-21-02并且范围查询包含此值因此我们得到了一个搜索结果。 之后我们仅在2014-04-01-00-00-00到2014-04-01-21-21-02之间进行搜索。 由于test-foods.txt的上一次修改时间为2014-04-01-21-21-02并且范围查询不包含此值因为已将其排除在外因此此搜索返回0个匹配。 此后接下来的四个搜索显示使用QueryParser对象执行的等效搜索。 请注意对于每个查询QueryParser的parse()方法都返回ConstantScoreRangeQuery对象而不是RangeQuery对象正如我们从这些查询的控制台输出中看到的那样。 4.6。前缀查询 与包含带有指定前缀的术语的文档匹配的Query 。 PrefixQuery由QueryParser构建用于类似nam *的输入。 我们将尝试使用两个文本文件test-foods.txt和sample-foods.txt使用前缀查询来搜索带有其前缀的特定术语。 对于这样做我们将增加一个名为方法searchIndexWithPrefixQuery()将搜索器的索引这将创建createIndex()使用PrefixQuery 。 此方法有两个参数一个是字段名另一个是搜索字符串。 public static void searchIndexWithPrefixQuery(String whichField, String searchString) throws IOException,ParseException {System.out.println(\\nSearching for searchString using PrefixQuery);Directory directory FSDirectory.getDirectory(INDEX_DIRECTORY);IndexSearcher indexSearcher new IndexSearcher(directory);Term term new Term(whichField, searchString);Query query new PrefixQuery(term);Hits hits indexSearcher.search(query);displayHits(hits);
} 接下来我们将从程序的main()方法中调用此方法– searchIndexWithPrefixQuery(FIELD_CONTENTS, test);searchIndexWithPrefixQuery(FIELD_CONTENTS, tes*); 在第一个查询中查询字符串不包含星号。 因此如果我们打印QueryParser的parse()方法的查询类型它将打印TermQuery而不是PrefixQuery 。 在第二查询中星号向QueryParser指示这是一个前缀查询因此它从其parse()方法返回PrefixQuery对象。 这导致在索引内容中搜索前缀“ tes”。 由于“ test”在索引中因此产生1次匹配。 4.7。模糊查询 模糊查询基于Damerau-Levenshtein最佳字符串对齐算法。 FuzzyQuery将术语“接近”匹配到指定的基本术语我们指定了一个允许的最大编辑距离并且在与基本术语然后包含这些术语的文档相距该编辑距离内的所有术语都将匹配。 QueryParser语法为QueryParser或QueryParser 其中N是允许的最大编辑数量对于较早的发行版N是0.0到1.0之间的令人困惑的浮点数它通过一个棘手的公式转换为等效的最大编辑距离。 FuzzyQuery非常适合匹配专有名称我们可以搜索lucene〜1它将匹配luccene插入clucee删除nlukene用k替换c和许多其他“接近”术语。 使用最大编辑距离2我们最多可以有2个插入删除或替换。 每次比赛的得分均基于该词的编辑距离 因此完全匹配的得分最高 编辑距离1降低 等等 QueryParser支持在词条上使用尾随波浪号的模糊词条查询。 例如搜索wuzza〜将找到包含“ fuzzy”和“ wuzzy”的文档。 编辑距离会影响评分因此较低的编辑距离会获得较高的分数。 翻译自: https://www.javacodegeeks.com/2015/09/advanced-lucene-query-examples.htmllucene 查询示例