对Lucene PhraseQuery的slop的理解

所谓PhraseQuery,就是经过短语来检索,好比我想查“big car”这个短语,那么若是待匹配的document的指定项里包含了"big car"这个短语,这个document就算匹配成功。可若是待匹配的句子里包含的是“big black car”,那么就没法匹配成功了,若是也想让这个匹配,就须要设定slop,先给出slop的概念:slop是指两个项的位置之间容许的最大间隔距离,下面我举例来解释:函数

   个人待匹配的句子是:the quick brown fox jumped over the lazy dog.ui

例1: 若是我想用“quick fox”来匹配出上面的句子,我发现原句里是quick [brown] fox,就是说和个人“quick fox”中间相差了一个单词的距离,因此,我这里把slop设为1,表示quickfox这两项之间最大能够容许有一个单词的间隔,这样全部“quick [***] fox”就均可以被匹配出来了。spa

例2:若是我想用“fox quick”来匹配出上面的句子,这也是能够的,不过比例1要麻烦,咱们须要看把“fox quick”怎么移动能造成“quick [***] fox”,以下表所示,把fox向右移动3次便可:.net

z1

例3:若是我想用“lazy jumped quick”该如何匹配上面的句子呢?这个比例2还要麻烦,咱们要考虑3个单词,无论多少个单词,slop表示的是间隔的最大距离,详细起见,咱们分别来看每种组合:(个人待匹配的句子是:the quick brown fox jumped over the lazy dog.)对象

  • lazy jumped:原句是jumped [over] [the] lazy,就是说它们两个之间间隔了2个词,以下所示:须要把lazy向右移动4位

z2

  • lazy jumped quick:咱们主要看lazyquick,可是因为jumped是在中间,因此移动的时候仍是要把jumped考虑在内,原句里lazyquick的关系是:quick [brown] [fox] [jumped] [over] [the] lazy ,quick lazy中间间隔了5个词,因此以下图所示,把lazy向右移动8次
  • z3
  • 最后是jumped qucik,这里不详细画表格了,你们能够本身试试,应该是把jumped向右移动4次。

   综合以上3种状况,因此咱们须要把slop设为8才令“lazy jumped quick”能够匹配到原句。ci

OK,就到这里吧,但愿对你们有帮助,若是我理解有误,也请指出,谢谢~文档

首先,强调一下PhraseQuery对象,这个对象不属于跨度查询类,但能完成跨度查询功能。get

匹配到的文档所包含的项一般是彼此相邻的,考虑到原文档中在查询项之间可能有一些中间项,或为了能查询倒排的项,PhraseQuery设置了slop因子,可是这个slop因子指2个项容许最大间隔距离,不是传统意义上的距离,是按顺序组成给定的短语,所须要移动位置的次数,这表示PhraseQuery是必须按照项在文档中出现的顺序计算跨度的,如quick brown fox为文档,则quick fox2个项的slop为1,quick向后移动一次.而fox quick须要quick向后移动3次,因此slop为3it

其次,来看一下SpanQuery的子类SpanTermQuery。io

它能跨度查询,而且不必定非要按项在文档中出现的顺序,能够用一个独立的标记表示查询对象必须按顺序,或容许按倒过来的顺序完成匹配。匹配的跨度也不是指移动位置的次数,是指从第一个跨度的起始位置到最后一个跨度的结束位置。

在SpanNearQuery中将SpanTermQuery对象做为SpanQuery对象使用的效果,与使用PharseQuery的效果很是类似。在SpanNearQuery的构造函数中的第三个参数为inOrder标志,设置这个标志,表示按项在文档中出现的顺序倒过来的顺序。

如:the quick brown fox jumps over the lazy dog这个文档

public void testSpanNearQuery() throws Exception{

SpanQuery[] quick_brown_dog=new SpanQuery[]{quick,brown,dog};

SpanNearQuery snq=new SpanNearQuery(quick_brown_dog,0,true);//按正常顺序,跨度为0,对三个项进行查询

assertNoMatches(snq);//没法匹配

SpanNearQuery snq=new SpanNearQuery(quick_brown_dog,4,true);//按正常顺序,跨度为4,对三个项进行查询

assertNoMatches(snq);//没法匹配

SpanNearQuery snq=new SpanNearQuery(quick_brown_dog,4,true);//按正常顺序,跨度为5,对三个项进行查询

assertOnlyBrownFox(snq);//匹配成功

SpanNearQuery snq=new SpanNearQuery(new SpanQuery[]{lazy,fox},3,false);//按相反顺序,跨度为3,对三个项进行查询

assertOnlyBrownFox(snq);//匹配成功

//下面使用PhraseQuery进行查询,由于是按顺序,因此lazy和fox必需要跨度为5

PhraseQuery pq=new PhraseQuery();

pq.add(new Term("f","lazy"));

pq.add(new Term("f","lazy"));

pq.setslop(4);

assertNoMatches(pq);//跨度4没法匹配

//PharseQuery,slop因子为5

pq.setSlop(5);

assertOnlyBrownFox(pq);

} 3.PhrasePrefixQuery 主要用来进行同义词查询的:     IndexWriter writer = new IndexWriter(directory, new WhitespaceAnalyzer(), true);     Document doc1 = new Document();     doc1.add(Field.Text("field", "the quick brown fox jumped over the lazy dog"));     writer.addDocument(doc1);     Document doc2 = new Document();     doc2.add(Field.Text("field","the fast fox hopped over the hound"));     writer.addDocument(doc2);     PhrasePrefixQuery query = new PhrasePrefixQuery();     query.add(new Term[] {new Term("field", "quick"), new Term("field", "fast")});     query.add(new Term("field", "fox"));     Hits hits = searcher.search(query);     assertEquals("fast fox match", 1, hits.length());     query.setSlop(1);     hits = searcher.search(query);     assertEquals("both match", 2, hits.length());

相关文章
相关标签/搜索