日期:2014-05-20  浏览次数:20760 次

关于lucene的PhraseQuery的菜鸟问题
本帖最后由 jutem 于 2014-04-01 15:24:00 编辑
运行测试的时候,slop无论是1还是0返回都是false。

public class MyPhraseQuery
{
public void setUp() throws Exception
{
dir=new RAMDirectory();
IndexWriter writer=getWriter();

Document doc=new Document();
doc.add(new StringField("field","the quick brown fox jumped over the lazy dog",Store.YES));
writer.addDocument(doc);
writer.close();

reader=DirectoryReader.open(dir);
searcher=new IndexSearcher(reader);
}

public void tearDown() throws IOException
{
reader.close();
dir.close();
}

public boolean matched(String [] phrase,int slop) throws IOException
{

PhraseQuery query=new PhraseQuery();
query.setSlop(slop);

for(String word:phrase)
{
query.add(new Term("field",word));
}

TopDocs matches=searcher.search(query, 10);
return matches.totalHits>0;
}

private IndexWriter getWriter() throws Exception {  
        Analyzer analyzer=new WhitespaceAnalyzer(Version.LUCENE_47); 
        IndexWriterConfig iwc=new IndexWriterConfig(Version.LUCENE_47, analyzer);  
        return new IndexWriter(dir, iwc);  
    }  

private Directory dir;
private IndexReader reader;
private IndexSearcher searcher;
}


public class MyPhraseQueryTest 
{
@Test
public void PhraseQueryTest() throws Exception
{
MyPhraseQuery q=new MyPhraseQuery();

q.setUp();

String[] phrase=new String[]{"quick","fox"};

System.out.println(q.matched(phrase,0)+" "+q.matched(phrase,1));

assertFalse("exact phrase not fount",q.matched(phrase,0));
assertTrue("close enough",q.matched(phrase,1));

q.tearDown();

}
}

------解决方案--------------------
新版本的lucene没玩过,老版本增加的时候有个指定是否需要分词的选项,就是这个Field.Index.TOKENIZED,表明需要分词并且索引,否则用Field.Index.UN_TOKENIZED不会分词,那肯定找不到。我奇怪的是新版本的新StringField难道不用指定这个参数?
Filed f = new Field("field","the quick brown fox jumped over the lazy dog",Field.Store.YES,
         Field.Index.TOKENIZED);//老版本必须指定这个参数,如果用Field.Index.UN_TOKENIZED就找不到