fix parsing of dates in range queries that use local date format: include the last day if query is inclusive

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@373355 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Daniel Naber 2006-01-29 20:51:43 +00:00
parent 9db7eaa951
commit 0f19da3c90
4 changed files with 83 additions and 5 deletions

View File

@ -333,6 +333,10 @@ Bug fixes
22. IndexWriter.setMaxBufferedDocs(1) didn't have the expected effect,
this has now been fixed. (Daniel Naber)
23. Fixed QueryParser when called with a date in local form like
"[1/16/2000 TO 1/18/2000]". This query did not include the documents
of 1/18/2000, i.e. the last day was not included. (Daniel Naber)
Optimizations
1. Disk usage (peak requirements during indexing and optimization)

View File

@ -517,6 +517,18 @@ public class QueryParser implements QueryParserConstants {
df.setLenient(true);
Date d1 = df.parse(part1);
Date d2 = df.parse(part2);
if (inclusive) {
// The user can only specify the date, not the time, so make sure
// the time is set to the latest possible time of that date to really
// include all documents:
Calendar cal = Calendar.getInstance(locale);
cal.setTime(d2);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
d2 = cal.getTime();
}
part1 = DateField.dateToString(d1);
part2 = DateField.dateToString(d2);
}

View File

@ -540,6 +540,18 @@ public class QueryParser {
df.setLenient(true);
Date d1 = df.parse(part1);
Date d2 = df.parse(part2);
if (inclusive) {
// The user can only specify the date, not the time, so make sure
// the time is set to the latest possible time of that date to really
// include all documents:
Calendar cal = Calendar.getInstance(locale);
cal.setTime(d2);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
d2 = cal.getTime();
}
part1 = DateField.dateToString(d1);
part2 = DateField.dateToString(d2);
}

View File

@ -26,18 +26,26 @@ import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateField;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.RAMDirectory;
import java.io.IOException;
import java.io.Reader;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Locale;
/**
* Tests QueryParser.
@ -342,23 +350,32 @@ public class TestQueryParser extends TestCase {
assertQueryEquals("gack ( bar blar { a TO z}) ", null, "gack (bar blar {a TO z})");
}
public String getDate(String s) throws Exception {
private String getDate(String s) throws Exception {
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
return DateField.dateToString(df.parse(s));
}
public String getLocalizedDate(int year, int month, int day) {
private String getLocalizedDate(int year, int month, int day, boolean extendLastDate) {
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
if (extendLastDate) {
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
}
return df.format(calendar.getTime());
}
public void testDateRange() throws Exception {
String startDate = getLocalizedDate(2002, 1, 1);
String endDate = getLocalizedDate(2002, 1, 4);
String startDate = getLocalizedDate(2002, 1, 1, false);
String endDate = getLocalizedDate(2002, 1, 4, false);
Calendar endDateExpected = Calendar.getInstance();
endDateExpected.set(2002, 1, 4, 23, 59, 59);
endDateExpected.set(Calendar.MILLISECOND, 999);
assertQueryEquals("[ " + startDate + " TO " + endDate + "]", null,
"[" + getDate(startDate) + " TO " + getDate(endDate) + "]");
"[" + getDate(startDate) + " TO " + DateField.dateToString(endDateExpected.getTime()) + "]");
assertQueryEquals("{ " + startDate + " " + endDate + " }", null,
"{" + getDate(startDate) + " TO " + getDate(endDate) + "}");
}
@ -537,6 +554,39 @@ public class TestQueryParser extends TestCase {
assertEquals(query1, query2);
}
public void testLocalDateFormat() throws IOException, ParseException {
RAMDirectory ramDir = new RAMDirectory();
IndexWriter iw = new IndexWriter(ramDir, new WhitespaceAnalyzer(), true);
addDateDoc("a", 2005, 12, 2, 10, 15, 33, iw);
addDateDoc("b", 2005, 12, 4, 22, 15, 00, iw);
iw.close();
IndexSearcher is = new IndexSearcher(ramDir);
assertHits(1, "[12/1/2005 TO 12/3/2005]", is);
assertHits(2, "[12/1/2005 TO 12/4/2005]", is);
assertHits(1, "[12/3/2005 TO 12/4/2005]", is);
assertHits(1, "{12/1/2005 TO 12/3/2005}", is);
assertHits(1, "{12/1/2005 TO 12/4/2005}", is);
assertHits(0, "{12/3/2005 TO 12/4/2005}", is);
is.close();
}
private void assertHits(int expected, String query, IndexSearcher is) throws ParseException, IOException {
QueryParser qp = new QueryParser("date", new WhitespaceAnalyzer());
qp.setLocale(Locale.ENGLISH);
Query q = qp.parse(query);
Hits hits = is.search(q);
assertEquals(expected, hits.length());
}
private static void addDateDoc(String content, int year, int month,
int day, int hour, int minute, int second, IndexWriter iw) throws IOException {
Document d = new Document();
d.add(new Field("f", content, Field.Store.YES, Field.Index.TOKENIZED));
Calendar cal = Calendar.getInstance();
cal.set(year, month-1, day, hour, minute, second);
d.add(new Field("date", DateField.dateToString(cal.getTime()), Field.Store.YES, Field.Index.UN_TOKENIZED));
iw.addDocument(d);
}
public void tearDown() {
BooleanQuery.setMaxClauseCount(originalMaxClauses);