2011-03-31 199 views
10

我试着用DateTools.dateToString()方法来索引日期。它适用于索引和搜索。Lucene中的索引和搜索日期

但我已经索引的数据有一些引用是这样的,它有一个新的索引日期为Date().getTime()

所以我的问题是,如何对这些数据进行RangeSearch Query ...

任何解决这一???

在此先感谢。

+0

哪个版本的lucene,Lucene <2.9仅执行Lexographic范围查询,您可能需要指定确切的日期格式! – Narayan 2011-03-31 05:36:08

+1

我正在使用2.9.1。我是否只需要使用特定的日期格式?它不适用于getTime()吗? – user660024 2011-04-01 07:04:34

回答

17

您需要在日期字段中使用TermRangeQuery。该字段总是需要编号为DateTools.dateToString()才能正常工作。这里有索引的完整示例和使用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总是很高兴看到工作代码 – Bohemian 2011-06-28 04:18:20

3

如果使用NumericField为你的约会你会得到更好的搜索性能,然后NumericRangeFilter /查询做到的范围内搜索。

你只需要将你的日期编码为long或int。一种简单的方法是调用Date的.getTime()方法,但这可能比您需要的分辨率(毫秒)要多得多。如果你只需要一天的时间,你可以将它编码为YYYYMMDD整数。

然后,在搜索时间,对您的开始/结束日期进行相同的转换并运行NumericRangeQuery/Filter。