2011-04-03 23 views
7

Estoy utilizando SpanTerm Query para buscar la frase exacta en lucene. Pero parece que no funciona. Aquí está mi código.Búsqueda de frase exacta con Lucene?

Indexación

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

Buscando

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

favor, me guía si estoy haciendo mal ???

Prateek

+0

uso de un analizador diferente que no sea la estándar, se salta palabras comunes, KeywordAnalyzer que mirarán hacia .. – Narayan

Respuesta

9

Pruebe un lugar 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); 

Editar: yo creo que hay un problema diferente. ¿Qué otras partes hay para su booleanQuery? Aquí está un ejemplo de trabajo completa de buscar una frase:

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

Gracias por el ejemplo. Fue una gran ayuda :) –

+0

¿Esta sería también una solución para http://stackoverflow.com/questions/15074812/lucene-search-on-a-hibernate-list-field? – theblang

2

Para la versión 4.6.0 Indexación:

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

la búsqueda de la frase exacta (dado en la palabra clave variable):

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

Nota para el uso de "setPhraseSlop (0) y createPhraseQuery()

Cuestiones relacionadas