2011-03-31 23 views
10

He intentado indexar la fecha con el método DateTools.dateToString(). Está funcionando correctamente para la indexación y la búsqueda.Fecha de indexación y búsqueda en Lucene

Pero mi información ya indexada que tiene algunas referencias es de tal manera que ha indexado la fecha como una nueva Date().getTime().

Así que mi problema es cómo llevar a cabo en estos datos RangeSearch Query ...

Cualquier solución a esto ???

Gracias de antemano.

+0

cuya versión de lucene, Lucene <2.9 realiza solo consultas de rango Lexographic, puede que necesite especificar el formato de fecha exacta en ese caso !! – Narayan

+1

Estoy usando 2.9.1. ¿Necesito usar solo formato de fecha específico? ¿No funcionará con getTime()? – user660024

Respuesta

17

Necesita usar un TermRangeQuery en su campo de fecha. Ese campo siempre debe indexarse ​​con DateTools.dateToString() para que funcione correctamente. Aquí está un ejemplo completo de indexación y búsqueda en un intervalo de fechas con Lucene 3.0:

public class LuceneDateRange { 
    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); 

     // use the current time as the base of dates for this example 
     long baseTime = System.currentTimeMillis(); 

     // index 10 documents with 1 second between dates 
     for (int i = 0; i < 10; i++) { 
      Document doc = new Document(); 
      String id = String.valueOf(i); 
      String date = buildDate(baseTime + i * 1000); 
      doc.add(new Field("id", id, Store.YES, Index.NOT_ANALYZED)); 
      doc.add(new Field("date", date, Store.YES, Index.NOT_ANALYZED)); 
      writer.addDocument(doc); 
     } 
     writer.close(); 

     // search for documents from 5 to 8 seconds after base, inclusive 
     IndexSearcher searcher = new IndexSearcher(directory); 
     String lowerDate = buildDate(baseTime + 5000); 
     String upperDate = buildDate(baseTime + 8000); 
     boolean includeLower = true; 
     boolean includeUpper = true; 
     TermRangeQuery query = new TermRangeQuery("date", 
       lowerDate, upperDate, includeLower, includeUpper); 

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

    public static String buildDate(long time) { 
     return DateTools.dateToString(new Date(time), Resolution.SECOND); 
    } 
} 
+0

+1 siempre es bueno ver el código de trabajo – Bohemian

3

que obtendrá mucho mejor rendimiento de la búsqueda si se utiliza un NumericField para su fecha, y luego NumericRangeFilter/Consulta para hacer la búsqueda por rango .

Solo tiene que codificar su fecha como larga o int. Una forma simple es llamar al método .getTime() de su Fecha, pero esto puede ser mucho más resolución (milisegundos) de lo que necesita. Si solo necesita hasta el día, puede codificarlo como un entero YYYYMMDD.

Luego, en el momento de la búsqueda, haga la misma conversión en sus fechas de inicio/finalización y ejecute NumericRangeQuery/Filter.

Cuestiones relacionadas