對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());

相關文章
相關標籤/搜索