对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.
? ?例1:?如果我想用“quick fox”來匹配出上面的句子,我發現原句里是quick [brown] fox,就是說和我的“quick fox”中間相差了一個單詞的距離,所以,我這里把slop設為1,表示quick和fox這兩項之間最大可以允許有一個單詞的間隔,這樣所有“quick [***] fox”就都可以被匹配出來了。
???例2:如果我想用“fox quick”來匹配出上面的句子,這也是可以的,不過比例1要麻煩,我們需要看把“fox quick”怎么移動能形成“quick [***] fox”,如下表所示,把fox向右移動3次即可:
| ? | fox | quick | ? | ? |
| 1 | ? | fox|quick | ? | ? |
| 2 | ? | quick | fox | ? |
| 3 | ? | quick | ? | fox |
????例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位
?
?
| ? | lazy | jumped | ? | ? | ? |
| 1 | ? | lazy|jumped | ? | ? | ? |
| 2 | ? | jumped | lazy | ? | ? |
| 3 | ? | jumped | ? | lazy | ? |
| 4 | ? | jumped | ? | ? | ?lazy? |
?
?
- ??lazy jumped?quick:我們主要看lazy和quick,但是由于jumped是在中間,所以移動的時候還是要把jumped考慮在內,原句里lazy和quick的關系是:quick [brown] [fox] [jumped] [over] [the] lazy ,quick lazy中間間隔了5個詞,所以如下圖所示,把lazy向右移動8次
| ? | ?lazy | jumped | quick | ? | ? | ? | ? | ? | ? |
| 1 | ?? | lazy|jumped | quick | ?? | ?? | ?? | ?? | ?? | ? |
| 2 | ?? | jumped | lazy|quick | ?? | ?? | ?? | ?? | ?? | ? |
| ?3? | ?? | jumped | quick | ?lazy? | ?? | ?? | ?? | ?? | ? |
| 4 | ?? | jumped | quick | ?? | lazy? | ?? | ?? | ?? | ? |
| ?5? | ?? | jumped | quick | ?? | ?? | lazy? | ?? | ?? | ? |
| 6 | ?? | jumped | quick | ?? | ?? | ?? | lazy? | ?? | ? |
| 7 | ?? | jumped | quick | ?? | ?? | ?? | ?? | lazy? | ? |
| 8 | ? | jumped | quick | ? | ? | ? | ? | ? | lazy? |
?
- ?最后是jumped qucik,這里不詳細畫表格了,大家可以自己試試,應該是把jumped向右移動4次。
?? 綜合以上3種情況,所以我們需要把slop設為8才令“lazy jumped?quick”可以匹配到原句。
OK,就到這里吧,希望對大家有幫助,如果我理解有誤,也請指出,謝謝~
?
?
?
??????首先,強調一下PhraseQuery對象,這個對象不屬于跨度查詢類,但能完成跨度查詢功能。
??????匹配到的文檔所包含的項通常是彼此相鄰的,考慮到原文檔中在查詢項之間可能有一些中間項,或為了能查詢倒排的項,PhraseQuery設置了slop因子,但是這個slop因子指2個項允許最大間隔距離,不是傳統意義上的距離,是按順序組成給定的短語,所需要移動位置的次數,這表示PhraseQuery是必須按照項在文檔中出現的順序計算跨度的,如quick brown fox為文檔,則quick fox2個項的slop為1,quick向后移動一次.而fox quick需要quick向后移動3次,所以slop為3
??????其次,來看一下SpanQuery的子類SpanTermQuery。
??????它能跨度查詢,并且不一定非要按項在文檔中出現的順序,可以用一個獨立的標記表示查詢對象必須按順序,或允許按倒過來的順序完成匹配。匹配的跨度也不是指移動位置的次數,是指從第一個跨度的起始位置到最后一個跨度的結束位置。
??????在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());
?
轉載于:https://www.cnblogs.com/fabaoyi/p/3894244.html
總結
以上是生活随笔為你收集整理的对Lucene PhraseQuery的slop的理解[转载]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Storm中的LocalState 代码
- 下一篇: 用数组实现从文件搜索帐户和验证密码