2011-04-03 113 views
7

我正在使用SpanTerm查詢在lucene中搜索精確的短語。但它似乎沒有工作。這是我的代碼。使用Lucene的精確短語搜索?

索引

IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), false,IndexWriter.MaxFieldLength.UNLIMITED); 
doc.add(new Field("contents", sb.toString(), Field.Store.YES, Field.Index.ANALYZED,Field.TermVector.WITH_POSITIONS_OFFSETS)); 
doc.add(new Field("imageid", imageDocument.getImageId(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
doc.add(new Field("title", imageDocument.getTitle(), Field.Store.YES, Field.Index.ANALYZED)); 
doc.add(new Field("country", imageDocument.getCountry(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
write.addDocument(doc); 

搜索

String sentence = searchParameters.get("searchExactWord"); 
String[] words = sentence.split(" "); 
String queryNoWord = ""; 
int i = 0; 
SpanTermQuery [] clause = new SpanTermQuery[words.length]; 
for (String word : words) 
{ 
    clause[i] = new SpanTermQuery(new Term("contents",word)); 
    i++; 
} 
SpanNearQuery query = new SpanNearQuery(clause, 0, true); 
booleanQuery.add(query, BooleanClause.Occur.MUST); 

請指引我,如果我做錯了???

Prateek

+0

使用比標準的另一個不同的分析儀,它跳過常用詞,keywordanalyzer你們看看.. – Narayan 2011-04-03 09:08:56

回答

9

嘗試PhraseQuery代替:

PhraseQuery query = new PhraseQuery(); 
String[] words = sentence.split(" "); 
for (String word : words) { 
    query.add(new Term("contents", word)); 
} 
booleanQuery.add(query, BooleanClause.Occur.MUST); 

編輯:我認爲你有一個不同的問題。你的booleanQuery還有哪些其他部件?下面是搜索短語的一個完整的工作示例:

public class LucenePhraseQuery { 
    public static void main(String[] args) throws Exception { 
     // setup Lucene to use an in-memory index 
     Directory directory = new RAMDirectory(); 
     Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30); 
     MaxFieldLength mlf = MaxFieldLength.UNLIMITED; 
     IndexWriter writer = new IndexWriter(directory, analyzer, true, mlf); 

     // index a few documents 
     writer.addDocument(createDocument("1", "foo bar baz")); 
     writer.addDocument(createDocument("2", "red green blue")); 
     writer.addDocument(createDocument("3", "test foo bar test")); 
     writer.close(); 

     // search for documents that have "foo bar" in them 
     String sentence = "foo bar"; 
     IndexSearcher searcher = new IndexSearcher(directory); 
     PhraseQuery query = new PhraseQuery(); 
     String[] words = sentence.split(" "); 
     for (String word : words) { 
      query.add(new Term("contents", word)); 
     } 

     // display search results 
     TopDocs topDocs = searcher.search(query, 10); 
     for (ScoreDoc scoreDoc : topDocs.scoreDocs) { 
      Document doc = searcher.doc(scoreDoc.doc); 
      System.out.println(doc); 
     } 
    } 

    private static Document createDocument(String id, String content) { 
     Document doc = new Document(); 
     doc.add(new Field("id", id, Store.YES, Index.NOT_ANALYZED)); 
     doc.add(new Field("contents", content, Store.YES, Index.ANALYZED, 
       Field.TermVector.WITH_POSITIONS_OFFSETS)); 
     return doc; 
    } 
} 
+0

感謝您的例子。這是一個很好的幫助:) – 2011-10-09 18:24:17

+0

這也是一個解決方案http://stackoverflow.com/questions/15074812/lucene-search-on-a-hibernate-list-field? – theblang 2013-04-16 16:21:48

2

對於版本4.6.0索引:

IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_46,analyzer); 
try { 
     IndexWriter iwriter=new IndexWriter(mDir,config); 
     iwriter.deleteAll(); 
     iwriter.commit(); 
     Document doc = new Document(); 

     doc.add(new Field(myfieldname,text,TextField.TYPE_STORED)); 
     iwriter.addDocument(doc); 
     iwriter.close(); 
} 

搜索精確短語(可變關鍵字給出):

DirectoryReader ireader=DirectoryReader.open(mDir); 
IndexSearcher isearcher=new IndexSearcher(ireader); 
QueryParser parser = new QueryParser(Version.LUCENE_46,myfieldname,analyzer); 
parser.setDefaultOperator(QueryParser.Operator.AND); 
parser.setPhraseSlop(0); 
Query query=parser.createPhraseQuery(myfieldname,keyword); 
ScoreDoc[] hits=isearcher.search(query, null, 1000).scoreDocs; 
nret=hits.length; 
ireader.close(); 

注意使用「setPhraseSlop(0)和createPhraseQuery()