对Lucene而言,每个域都是String类型。然而在真实的应用中,我们还会遇到诸如日期、整数、浮点数等其它类型。如何是好?Lucene自然有其处理之道。
先让我们来看看Lucene是怎么处理日期类型的吧!
日期类型的使用场景可谓多之又多:邮件的寄出、收到日期;文件的创建日期、最后修改日期;HTTP响应中的最后修改日期等等。总之,绝大多数情况下,你会有处理日期的遭遇!Don't worry! Lucene为我们装备了一个处理日期的利器:DateTools. 通过它,我们可以便捷的把Date型转换成String型:
Document doc = new Document();
doc.add(new Field("indexDate",
DateTools.dateToString(new Date(), DateTools.Resolution.DAY),
Field.Store.YES,
Field.Index.NOT_ANALYZED));
DateTools 可以把日期和时间转换成 YYYYMMDDhhmmss 的格式,并根据指定的resolution去除相应后缀。比如你指定了Resolution.DAY,2012年12月21日就会被转换成20121221,时分秒部分会被去除掉。这么一来,就很容易发现,即便是按字符串进行排序、比较,也能得到和日期相同的效果。字符串"20121221"是大于"20121121"的,而其对应的日期也是如此。采用这种方式处理日期是不是很简单?参数resolution允许你截取对你的应用有意义的日期部分,精确度从Resolution.MILLISECOND(毫秒)到Resolution.YEAR(年),但是值得注意的是,更高的精度就需要付出更大的代价!
提醒你一下,如果你的应用中需要搜索一个YYYYMMDD范围内的数据,而在展示的时候又希望把时间部分(hhhmmss)也带上,你可以尝试创建两个域,一个索引到Resolution.DAY范围,另一个仅仅设置Store.
最后,我给出一个完整的例子:
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import junit.framework.TestCase;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
public class IndexDateTest extends TestCase{
private Directory directory;
protected void setUp() throws Exception {
Calendar cal = Calendar.getInstance();
cal.set(2011, 5, 10);
Date date = new Date(cal.getTimeInMillis());
directory = new RAMDirectory();
IndexWriter writer = getWriter();
Document doc = new Document();
doc.add(new Field("indexDate",
DateTools.dateToString(date, DateTools.Resolution.DAY),
Field.Store.YES,
Field.Index.NOT_ANALYZED));
writer.addDocument(doc);
writer.close();
}
public void testDateIndex() throws IOException {
IndexSearcher is = new IndexSearcher(directory);
Query query = new TermQuery(new Term("indexDate", "20110610"));
TopDocs topDocs = is.search(query, 1);
ScoreDoc[] docs = topDocs.scoreDocs;
Document doc = is.doc(docs[0].doc);
assertEquals("20110610", doc.get("indexDate"));
}
private IndexWriter getWriter() throws IOException {
return new IndexWriter(directory, new WhitespaceAnalyzer(),
IndexWriter.MaxFieldLength.UNLIMITED);
}
}