lucene学习(4)

2019-03-03 11:36

能力正好可以弥补缺陷。 另外,得益于当今操作系统的I/O缓存机制,重新查询操作通常会很快完成,因为该操作所 需要处理的磁盘数据已经被缓存至RAM 了。

3.1 lucene评分机制

相似度评分公式,用来衡量查询语句和对应匹配文档之间的相似程度。分值计算方式为查询语句(q)中每个项(t)与文档(d)的匹配分值之和。

得到原始评分,然后对评分进行归一化处理,即用该条查询对应的评分除以最大评分。

IndexSearcher类包含一个explain方法,调用该方法需要传入一个Query对象和一个文档ID,然后该方法会返回一个Explanation对象。该对象包含评分计算的各种信息细节。

短语査询是根据短语匹配所需要的编辑距离来进行评分的。项之间的距离越小,具 有的权重也就越大。评分与距离成反比关系,距离越大的匹配其评分越低。

1

distance?13.2 预置查询类

查询最终是调用IndexSearcher.search方法,该方法需要Query对象作为参数,该对象可以由QueryParser分析产生,也可以使用预置的Query对象。

3.2.1 TermQuery 通过项搜索

对索引中特定项进行搜索是最基本的搜索方式。Term是最小的索引片段,每个Term 包含了一个域名和一个文本值。下面这段代码 初始化了一个Term实例: Term t = new Term(\

TermQuery构造方法允许一个单独的Term对象作为其参数: Query query = new TermQuery(t);

使用这个TermQuery对象进行搜索,可以返回在content域包含单词“java”的所有文档。值得注意的是,该査询值是区分大小写的,因此搜索前一定要对索引后的项大小写进行匹配。

3.2.2在指定的项范围内捜索:TermRangeQuery类

索引中的各个Term对象会按照字典编排顺序(通过String.compareTo方法)进行排序,并允许在Lucene的TermRangeQuery对象提供的范围内进行文本项的直接搜索。 搜索时包含或不包含起始项和终止项。如果这个项为空,那么它对应的端就是无边界的。 举例来说,一个空的lowerTerm意味着没有下边界,这样所有比上边界项小的项都会 被计算在内。该査询只适用于文本范围,比如搜索从N到Q范围内的域名称。下一节 提到的NumericRangeQuery可以用于数值域的范围查询。

下面的代码为TermRangeQuery的使用方法,其功能是搜索起始字母范围从d到j 的书籍标题。这里需要注意,书籍索引中的title2域是小写字母形式的,并使用Field. NOT_ANALYZED_NO_NORMS将该域索引成单个语汇单元。 public void testTermRangeQuery{) throws Exception { Directory dir = TestUtil.genBooklndexDirectory(); IndexSearcher searcher = new IndexSearcher(dir);

TermRangeQuery query = new TermRangeQuery ( \true, true);

TopDocs matches = searcher.search(query, 100); assertEquals(3, matches.totalHits);

searcher.close(); dir.close(); }

其中TermRangeQuery初始化方法中的的两个Boolean对象参数表示是(用true 表示)否(用false表示)包含捜索范围的起点或终点。该对象还可以处理自定义的Collator对象,并用于搜索范围的检查,但对于大的索引来说,这个处理异常缓慢,因为他在检查边界条件时需要列举出索引的每个项。CollationKeyAnalyzer可以提高程序性能。

3.2.3在指定的数字范围内捜索:NumericRangeQuery类

如果使用NumericField对象来索引域,那么你就能有效地使用NumericRange Query类在某个特定范围内搜索该域。Lucene会在后台将提交的搜索范围转换成与前面索引操作生成的树结构(trie structure)等效的括号集。这里每个括号都是索引中各不相同的项,它们对应的文档都会在搜索时进行或运算。使用NumericRangeQuery类搜索时所需要的括号数量相对较小,这使得该类运行时与TermRangeQuery类相比,性能好很多。

下面的程序示例,该程序基于书籍索引中的pub month域运行。程序将该域作为整数进行索引,并且索引精度为月,也就是说,2010年3月会被索引成域值为 201003的NumericField。程序接下来进行了一次范围内搜寻:

public void testlnclusive() throws Exception { Directory dir = TestUtil.getBooklndexDirectory(); IndexSearcher searcher = new IndexSearcher(dir); // pub date of TTC was September 2006

NainericRangeQuery query = NumericRangeQuery.newIntRange ( \200605,

200609, true, true);

TopDocs matches = searcher.search(query, 10); assertEquals(1, matches.totalHits); searcher.close(); dir.close{); }

程序最后newIntRange方法中的两个Boolean参数 表示搜索范围是(用true表示)否(用false表示)包含起点和终点。

该类可传入与NumericField相同的precisionStep参数。该参数的匹配详见Java文档。

3.2.4通过字符串捜索:PrefixQuery类

搜索程序使用PrefixQuery来搜索包含以指定字符串开头的项的文档。这个操作看起来是很容易的。下面的代码展示了如何通过简单的PrefixQuery对象对某个层次结构进行递归査询。包含category域的文档会呈现一个层次结构,该结构可以完美地用于匹配一个PrefixQuery对象

public class PrefixQueryTest extends TestCase { public void testPrefix() throws Exception {

Directory dir = TestUtil.getBooklndexDirectory(); IndexSearcher searcher = new IndexSearcher(dir); Term term = new Term(\

\;

PrefixQuery query = new PrefixQuery(term); //搜索编程方面的书籍,包括它们的子类书籍 TopDocs matches = searcher.search(query, 10); int progratnmingAndBelow = matches. totalHits; // 搜素编程方面的书籍不包括它们的子类

matches = searcher. search (new TermQuery (term) , 10) ; int justProgramming = matches.totalHits

assertTrue(programmingAndBelow > justPrograiraming); searcher.close(); dir.close(); } }

PrefixQueryTest 类展示了 PrefixQuery 和 TermQuery 之间的差异。methodology 分类存在于/technology/computers/programming分类目录下。在这个methodology子类中的书籍程序通过PrefixQuery,而不是通过TermQuery找到的。

3.2.5组合查询:BooleanQuery 类

通过使用BooleanQuery类可以将本章讨论的各种查询类型组合成复杂的查询方式, 而BooleanQuery本身是一个Boolean子句(clauses)的容器。这个子句可以是表示逻辑 “与”、逻辑“或”或者逻辑“非”的一个子査询。这些属性允许

进行逻辑AND、OR和NOT 组合。你可以调用如下API的方法将査询子句加入到BooleanQuery对象中:

public void add(Query query, BooleanClause.Occur occur)

这里 Occur 对象可以设置为 BooleanClause .Occur .MUST、BooleanClause.Occur. SHOULD 或者 BooleanClause. Occur.MUST_NOT。BooleanQuery对象还可以作为另一个BooleanQuery对象的字句,这样就允许它们任意地嵌套了。 public void testAnd() throws Exception { TermQuery searchingBooks =

new TermQuery (new Term( \; Query books2010 =

NumericRangeQuery.newIntRange(\ 201012, true, true);

BooleanQuery searchingBooks2010 = new BooleanQuery();

searchingBooks2010.add(searchingBooks, BooleanClause.Occur.MUST); ? searchingBooks2010.add(books2010, BooleanClause.Occur.MUST); Directory dir = TestUtil.getBooklndexDirectory(); IndexSearcher searcher = new IndexSearcher(dir);

TopDocs matches = searcher.search{searchingBooks2010, 10); assertTrue(TestUtil.hitslncludeTitle(searcher, matches, .\searcher.close(); dir.close(); )

BooleanClause.Occur.MUST的精确含义是:只有匹配该查询子句的文档才在考虑之列。BooleanClause. Occur .SHOULD意味着该项只是可选项,可用于或选项。BooleanClause. Occur .MUST_NOT意味着搜索结果不会包含任何匹配该查询子句的文档。

BooleanQuery对其中包含的查询子句是有数量限制的,默认情况下允许包含1024 个査询子句。该限制主要是为了防止时对应用程序的性能造成影响。当子句数量超过最大 值时,程序会抛出TooManyClauses异常。对于Lucene早期版本来说,这个限制是必要 的,因为某些查询语句可能会在后台被改写成等效的BooleanQuery类。但从版本2.9开始, Lucene会以一种更有效地方式处理这些查询语句。如果你在一些特殊情况下需要增大查 询子句的数量限制,可以使用BooleanQuery类提供的ClauseCount (int)方法进行设置,但设置前需要意识到这个做法对程序性能产生的影响。


lucene学习(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:星级酒店餐厅菜单之认识

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: