mirror of https://github.com/apache/lucene.git
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:
parent
9db7eaa951
commit
0f19da3c90
|
@ -333,6 +333,10 @@ Bug fixes
|
||||||
22. IndexWriter.setMaxBufferedDocs(1) didn't have the expected effect,
|
22. IndexWriter.setMaxBufferedDocs(1) didn't have the expected effect,
|
||||||
this has now been fixed. (Daniel Naber)
|
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
|
Optimizations
|
||||||
|
|
||||||
1. Disk usage (peak requirements during indexing and optimization)
|
1. Disk usage (peak requirements during indexing and optimization)
|
||||||
|
|
|
@ -517,6 +517,18 @@ public class QueryParser implements QueryParserConstants {
|
||||||
df.setLenient(true);
|
df.setLenient(true);
|
||||||
Date d1 = df.parse(part1);
|
Date d1 = df.parse(part1);
|
||||||
Date d2 = df.parse(part2);
|
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);
|
part1 = DateField.dateToString(d1);
|
||||||
part2 = DateField.dateToString(d2);
|
part2 = DateField.dateToString(d2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -540,6 +540,18 @@ public class QueryParser {
|
||||||
df.setLenient(true);
|
df.setLenient(true);
|
||||||
Date d1 = df.parse(part1);
|
Date d1 = df.parse(part1);
|
||||||
Date d2 = df.parse(part2);
|
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);
|
part1 = DateField.dateToString(d1);
|
||||||
part2 = DateField.dateToString(d2);
|
part2 = DateField.dateToString(d2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,18 +26,26 @@ import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||||
import org.apache.lucene.document.DateField;
|
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.BooleanQuery;
|
||||||
import org.apache.lucene.search.FuzzyQuery;
|
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.PhraseQuery;
|
||||||
import org.apache.lucene.search.PrefixQuery;
|
import org.apache.lucene.search.PrefixQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.RangeQuery;
|
import org.apache.lucene.search.RangeQuery;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.apache.lucene.search.WildcardQuery;
|
import org.apache.lucene.search.WildcardQuery;
|
||||||
|
import org.apache.lucene.store.RAMDirectory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests QueryParser.
|
* 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})");
|
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);
|
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
|
||||||
return DateField.dateToString(df.parse(s));
|
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);
|
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
calendar.set(year, month, day);
|
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());
|
return df.format(calendar.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDateRange() throws Exception {
|
public void testDateRange() throws Exception {
|
||||||
String startDate = getLocalizedDate(2002, 1, 1);
|
String startDate = getLocalizedDate(2002, 1, 1, false);
|
||||||
String endDate = getLocalizedDate(2002, 1, 4);
|
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,
|
assertQueryEquals("[ " + startDate + " TO " + endDate + "]", null,
|
||||||
"[" + getDate(startDate) + " TO " + getDate(endDate) + "]");
|
"[" + getDate(startDate) + " TO " + DateField.dateToString(endDateExpected.getTime()) + "]");
|
||||||
assertQueryEquals("{ " + startDate + " " + endDate + " }", null,
|
assertQueryEquals("{ " + startDate + " " + endDate + " }", null,
|
||||||
"{" + getDate(startDate) + " TO " + getDate(endDate) + "}");
|
"{" + getDate(startDate) + " TO " + getDate(endDate) + "}");
|
||||||
}
|
}
|
||||||
|
@ -537,6 +554,39 @@ public class TestQueryParser extends TestCase {
|
||||||
assertEquals(query1, query2);
|
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() {
|
public void tearDown() {
|
||||||
BooleanQuery.setMaxClauseCount(originalMaxClauses);
|
BooleanQuery.setMaxClauseCount(originalMaxClauses);
|
||||||
|
|
Loading…
Reference in New Issue