网站设计与管理方向nas 做网站服务器
news/
2025/9/23 21:41:52/
文章来源:
网站设计与管理方向,nas 做网站服务器,公司网站推广的方法,淄博 网站推广lucene 查询示例本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要#xff0c;然后了解Lucene中搜索的工作方式。 此外#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中… lucene 查询示例 本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中您将了解Lucene。 您将了解为什么这样的库很重要然后了解Lucene中搜索的工作方式。 此外您将学习如何将Lucene Search集成到您自己的应用程序中以提供强大的搜索功能。 在这里查看 目录 1.简介 2.查询类 2.1术语查询 2.2短语查询 2.3。 布尔查询 2.4。 通配符查询 2.5。 正则表达式查询 2.6。 TermRangeQuery 2.7。 NumberRangeQuery 2.8。 模糊查询 1.简介 在本课程的这一课中我们将研究Lucene提供的基本查询机制。 您可能会在入门课程中记得Lucene不会将要搜索的原始文本发送到索引。 为此它使用Query对象。 在本课程中我们将看到所有关键要素它们将人类书面搜索短语转换为诸如Queries类的代表性结构。 2.查询类 Query类是一个公共抽象类它代表对索引的查询。 在本节中我们将看到最重要的Query子类您可以使用它们来执行高度定制的查询。 2.1术语查询 这是您可以针对Lucene索引执行的最简单直接的查询。 您只需搜索在特定Field包含单个单词的Documents 。 基本的TermQuery构造函数定义如下 public TermQuery(Term t) 。 您从第一节课中记得 Term由两部分组成 该术语所驻留的Field的名称。 术语的实际值在大多数情况下是通过对某些纯文本的分析得出的单个单词。 因此如果您想创建一个TermQuery来查找所有在content Field中包含good字样的Documents 则可以按照以下方法进行操作 TermQuery termQuery new TermQuery(new Term(content,good)); 我们可以使用它在先前创建的索引中搜索单词“ static” String q staticDirectory directory FSDirectory.open(indexDir);IndexReader indexReader DirectoryReader.open(directory);IndexSearcher searcher new IndexSearcher(indexReader);Analyzer analyzer new StandardAnalyzer(Version.LUCENE_46);TermQuery termQuery new TermQuery(new Term(content,q));TopDocs topDocs searcher.search(termQuery, maxHits);ScoreDoc[] hits topDocs.scoreDocs;for (ScoreDoc hit : hits) {int docId hit.doc;Document d searcher.doc(docId);System.out.println(d.get(fileName) Score : hit.score);
}System.out.println(Found hits.length); 输出为 C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\Product.java Score :0.29545835
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleSearcher.java Score :0.27245367
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\PropertyObject.java Score :0.24368995
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleIndexer.java Score :0.14772917
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\TestSerlvet.java Score :0.14621398
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\ShoppingCartServlet.java Score :0.13785185
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\MyServlet.java Score :0.12184498
Found 7 如您所见我的七个源文件中包含static关键字。 就是这样。 自然如果您尝试在查询字符串中添加另一个单词搜索将返回0个结果。 例如如果您将查询字符串设置为 String q private static 输出为 Found 0 现在我知道我的许多源文件中都存在private static 。 但是您可能还记得我们在索引过程中使用了StandarAnalyzer处理从文件中检索的纯文本。 StandardAnalyzer将文本拆分为单个单词因此每个Term包含一个单词。 您可以选择不标记索引的Field 。 但是我建议您在包含元数据的Fields中执行此操作而不是在包含其内容的字段中这些字段包含有关文档的信息例如标题或作者。 例如如果您选择不对名称为author且值为James Wilslow的Field进行标记化并编制索引则Field author将仅包含一个整体值为James Wilslow Term 。 如果您对Field进行了标记化则它将包含两个Terms 一个的值为James 另一个的值为Wilslow 。 2.2短语查询 使用PhraseQuery您可以搜索包含特定单词序列又名短语的Documents 。 您可以这样创建一个PhraseQuery PhraseQuery phraseQuery new PhraseQuery(); 然后您可以向其添加Terms 。 例如如果您要搜索在其“内容”字段中包含短语“ private static”的Documents 则可以这样做 PhraseQuery phraseQuery new PhraseQuery();phraseQuery.add(new Term(content,private));
phraseQuery.add(new Term(content,static));TopDocs topDocs searcher.search(phraseQuery, maxHits);ScoreDoc[] hits topDocs.scoreDocs;for (ScoreDoc hit : hits) {int docId hit.doc;Document d searcher.doc(docId);System.out.println(d.get(fileName) Score : hit.score);
}System.out.println(Found hits.length); 输出为 C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\Product.java Score :0.54864377
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\PropertyObject.java Score :0.45251375
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleSearcher.java Score :0.45251375
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\TestSerlvet.java Score :0.27150828
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\ShoppingCartServlet.java Score :0.25598043
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\MyServlet.java Score :0.22625688
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleIndexer.java Score :0.22398287
Found 7 仅当“ Field static连续且以准确顺序同时包含单词private和static Document才进入结果。 因此如果您以上述方式更改上面的代码 phraseQuery.add(new Term(content,private));
phraseQuery.add(new Term(content,final)); 你会得到 Found 0 这是因为尽管我的源文件包含两个词但它们不是连续的。 要改变这种行为一点点你可以添加一个slop到PhraseQuery 。 当斜率增加1时您最多允许一个词插入词组中的词之间。 添加坡度2时短语中的单词之间最多允许2个单词。 有趣的是 “实际上坡度是一个编辑距离其单位对应于查询短语中词条移动的位置。 例如要切换两个单词的顺序需要两个步骤第一个步骤将单词彼此放在首位因此要允许对短语进行重新排序斜率必须至少为两个。 因此如果这样做 PhraseQuery phraseQuery new PhraseQuery();phraseQuery.add(new Term(content,private));
phraseQuery.add(new Term(content,final));phraseQuery.setSlop(2); 我们的搜索输出将给出 C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\Product.java Score :0.38794976
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\PropertyObject.java Score :0.31997555
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleSearcher.java Score :0.31997555
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\TestSerlvet.java Score :0.19198532
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\ShoppingCartServlet.java Score :0.18100551
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\MyServlet.java Score :0.15998778
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleIndexer.java Score :0.15837982 重要的是要提到包含更接近查询确切短语的短语的文档将获得更高的分数。 2.3布尔查询 BooleanQuery是一种更具表现力和功能的工具因为您可以将多个查询与布尔子句结合在一起。 可以使用BooleanClauses填充BoleanQuery。 BooleanClause包含一个Query 以及Query在布尔搜索中应具有的角色。 更具体地说布尔子句可以在查询中扮演以下角色 MUST 这是自我explenatory 。 当且仅当Document包含该子句时它才会进入结果列表。 MUST NOT 这是完全相反的情况。 对于文档而言必须将其包含在结果列表中而不包含该子句。 SHOULD 这是针对Document中可能出现的子句的但是为了使结果成为结果它们没有必要包含这些子句。 如果仅使用SHOULD子句进行布尔查询则结果至少匹配其中一个子句。 这看起来像经典的OR布尔运算符但正确使用它并不是那么简单。 现在让我们看一些例子。 让我们找到包含单词“ string”但不包含单词“ int”的源文件。 TermQuery termQuery new TermQuery(new Term(content,string));
TermQuery termQuery2 new TermQuery(new Term(content,int));BooleanClause booleanClause1 new BooleanClause(termQuery, BooleanClause.Occur.MUST);
BooleanClause booleanClause2 new BooleanClause(termQuery2, BooleanClause.Occur.MUST_NOT);BooleanQuery booleanQuery new BooleanQuery();
booleanQuery.add(booleanClause1);
booleanQuery.add(booleanClause2);TopDocs topDocs searcher.search(booleanQuery, maxHits); 结果如下 C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\SimpleEJB.java Score :0.45057273
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\PropertyObject.java Score :0.39020744
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\ShoppingCartServlet.java Score :0.20150226
C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\TestSerlvet.java Score :0.13517183
Found 4 现在让我们尝试查找包含单词“ nikos”和短语“ httpservletresponse response”的所有文档。 在以下代码片段中您可以看到如何避免创建BooleanClause实例从而使您的代码更紧凑。 TermQuery termQuery new TermQuery(new Term(content,nikos));PhraseQuery phraseQuery new PhraseQuery();
phraseQuery.add(new Term(content,httpservletresponse));
phraseQuery.add(new Term(content,response));BooleanQuery booleanQuery new BooleanQuery();booleanQuery.add(phraseQuery,BooleanClause.Occur.MUST);
booleanQuery.add(termQuery,BooleanClause.Occur.MUST);TopDocs topDocs searcher.search(booleanQuery, maxHits); 结果如下 C:\\Users\\nikos\\Desktop\\LuceneFolders\\LuceneHelloWorld\\SourceFiles\\ShoppingCartServlet.java Score :0.3148332
Found 1 让我们找到所有包含单词“ int”或单词“ nikos”的文档。当您可能要成像时必须以某种方式使用SHOULD规范 TermQuery termQuery new TermQuery(new Term(content,int));
TermQuery termQuery2 new TermQuery(new Term(content,nikos));BooleanQuery booleanQuery new BooleanQuery();booleanQuery.add(termQuery,BooleanClause.Occur.SHOULD);
booleanQuery.add(termQuery2,BooleanClause.Occur.SHOULD);TopDocs topDocs searcher.search(booleanQuery, maxHits); 这虽然不太困难但是创建更复杂的析取查询有点棘手。 如何正确使用它并不总是那么简单。 例如让我们尝试查找所有包含单词“ nikos”和短语“ httpservletresponse response”或单词“ int”的文档。 一个人可以这样写 TermQuery termQuery new TermQuery(new Term(content,nikos));PhraseQuery phraseQuery new PhraseQuery();
phraseQuery.add(new Term(content,httpservletresponse));
phraseQuery.add(new Term(content,response));BooleanQuery booleanQuery new BooleanQuery();booleanQuery.add(phraseQuery,BooleanClause.Occur.MUST);
booleanQuery.add(termQuery,BooleanClause.Occur.MUST);
booleanQuery.add(new TermQuery(new Term(content,int)),BooleanClause.Occur.SHOULD);TopDocs topDocs searcher.search(booleanQuery, maxHits); 但是查询将无法提供所需的结果。 请记住如我们所构造的那样此查询的结果必须同时包含单词nikos并且必须同时包含短语httpservletresponse response 。 但这不是您想要的。 您需要包含nikos单词和短语httpservletresponse response文档但也希望独立包含单词int文档无论它们是否包含其他子句。 公平地说上述布尔查询有点错误。 因为用直接的布尔语法您永远都不会这样写A AND B ORC。您应该写A AND BORC。或者A ANDB OR C。 看到不同 因此您应该编写所需的查询“ nikos”和“ httpservletresponse response”或“ int”。 您可以将BooleanQueries组合在一起。 使用上面严格的语法很难想象这将如何进行 TermQuery termQuery new TermQuery(new Term(content,nikos));PhraseQuery phraseQuery new PhraseQuery();
phraseQuery.add(new Term(content,httpservletresponse));
phraseQuery.add(new Term(content,response));// (A AND B)
BooleanQuery conjunctiveQuery new BooleanQuery();
conjunctiveQuery.add(termQuery,BooleanClause.Occur.MUST);
conjunctiveQuery.add(phraseQuery,BooleanClause.Occur.MUST);BooleanQuery disjunctiveQuery new BooleanQuery();// (A AND B) OR C
disjunctiveQuery.add(conjunctiveQuery,BooleanClause.Occur.SHOULD);
disjunctiveQuery.add(new TermQuery(new Term(content,int)),BooleanClause.Occur.SHOULD);TopDocs topDocs searcher.search(disjunctiveQuery, maxHits); 这是使用BooleanQuery类构造布尔查询时可以遵循的快速指南 X和Y BooleanQuery bool new BooleanQuery();
bool.add(X,BooleanClause.Occur.MUST);
bool.add(Y,BooleanClause.Occur.MUST); X或Y BooleanQuery bool new BooleanQuery();
bool.add(X,BooleanClause.Occur.SHOULD);
bool.add(Y,BooleanClause.Occur.SHOULD); X AND不是Y BooleanQuery bool new BooleanQuery();
bool.add(X,BooleanClause.Occur.MUST);
bool.add(Y,BooleanClause.Occur.MUST_NOT); X和Y或Z BooleanQuery conj new BooleanQuery();conj.add(X,BooleanClause.Occur.MUST);
conj.add(Y,BooleanClause.Occur.MUST);BooleanQuery disj new BooleanQuery();
disj.add(conj,BooleanClause.Occur.SHOULD)
disj.add(Z,BooleanClause.Occur.SHOULD) X或Y和Z BooleanQuery conj new BooleanQuery();conj.add(X,BooleanClause.Occur.SHOULD);
conj.add(Y,BooleanClause.Occur.SHOULD);BooleanQuery disj new BooleanQuery();
disj.add(conj,BooleanClause.Occur.MUST)
disj.add(Z,BooleanClause.Occur.MUST) X或非Z BooleanQuery neg new BooleanQuery();neg.add(Z,BooleanClause.Occur.MUST_OT);BooleanQuery disj new BooleanQuery();
disj.add(neg,BooleanClause.Occur.SHOULD)
disj.add(X,BooleanClause.Occur.SHOULD) 上面的代码可用于创建越来越复杂的布尔查询。 2.4通配符查询 顾名思义您可以使用WildcardQuery类使用“ *”或“”执行通配符查询。 字符。 例如如果要o搜索包含以ni开头的词条然后是其他任何字符序列的文档则可以搜索ni *。 如果要搜索以“ jamie”开头后接任意一个字符的术语则可以搜索“ jamie”。 就那么简单。 自然地 WildcardQueries效率低下因为搜索可能要经过很多不同的术语才能找到匹配项。 通常最好避免将通配符放在单词的开头例如“ * abcde”。 让我们来看一个例子 Query wildcardQuery new WildcardQuery(new Term(content,n*os));
TopDocs topDocs searcher.search(wildcardQuery, maxHits); 和 Query wildcardQuery new WildcardQuery(new Term(content,niko?));
TopDocs topDocs searcher.search(wildcardQuery, maxHits);2.5 RegexpQuery 使用RegexpQuery 您可以执行快速的正则表达式查询并通过Lucene的快速自动机实现对其进行评估。 这是一个例子 Query regexpQuery new RegexpQuery(new Term(content,n[a-z]));TopDocs topDocs searcher.search(regexpQuery, maxHits);2.6 TermRangeQuery 当对字符串术语执行范围查询时此查询子类很有用。 例如您可以搜索“ abc”和“ xyz”两个词之间的字词。 字的比较是使用Byte.compareTo(Byte)执行的。 您可能会发现这对于在文档元数据中进行范围查询例如标题甚至日期特别有用如果使用日期请小心使用DateTools 。 以下是查找上周创建的所有文档的方法 Calendar c Calendar.getInstance();
c.add(Calendar.DATE, -7);
Date lastWeek c.getTime();Query termRangeQuery TermRangeQuery.newStringRange(date, DateTools.dateToString(new Date(), DateTools.Resolution.DAY),DateTools.dateToString(lastWeek, DateTools.Resolution.DAY),true,true); 当然在为“日期”字段建立索引时必须小心。 您还必须将DateTools.dateToString应用于它并指定不进行分析的字段这样就不会标记化该字段并将其拆分为单词。 2.7 NumberRangeQuery 这用于执行数字范围查询。 想象一下您有一个“ wordcount”字段用于存储该文档的单词数并且您要检索的单词数在2000到10000之间 Query numericRangeQuery NumericRangeQuery.newIntRange(wordcount,2000,10000,true,true); 布尔参数指示范围内包括上限和下限。 2.8模糊查询 这是一个非常有趣的查询子类。 该查询根据邻近度量例如众所周知的Damerau-Levenshtein距离评估字词。 这将找到词典顺序接近的单词。 如果您想执行复杂的词典应用程序例如词典或“您要说的话”字词建议功能则可以使用SpellChecker API 。 让我们看看如何执行不幸的“字符串”拼写错误的模糊查询搜索 Query fuzzyQuery new FuzzyQuery(new Term(content,srng));翻译自: https://www.javacodegeeks.com/2015/09/lucene-query-search-syntax-examples.htmllucene 查询示例
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913973.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!