Skip to content

Commit

Permalink
Made symbolic date math a reality
Browse files Browse the repository at this point in the history
  • Loading branch information
romanchyla committed Aug 21, 2019
1 parent 1e9a8a0 commit 4a8f2eb
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package org.apache.solr.search;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
Expand All @@ -24,7 +28,6 @@
import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
import org.apache.lucene.queryparser.flexible.standard.config.NumberDateFormat;
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler;
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator;
import org.apache.lucene.search.Query;
Expand All @@ -35,6 +38,7 @@
import org.apache.solr.schema.IndexSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.solr.util.DateMathParser;

/**
* This is the MAIN solr entry point - this instantiates 'aqp' query
Expand All @@ -52,6 +56,7 @@ public class AqpAdsabsQParser extends QParser {
public static TimeZone UTC = TimeZone.getTimeZone("UTC");
public static final Logger log = LoggerFactory
.getLogger(AqpAdsabsQParser.class);


private AqpQueryParser qParser;

Expand Down Expand Up @@ -251,6 +256,49 @@ public AqpAdsabsQParser(AqpQueryParser parser, String qstr, SolrParams localPara

}

public class NumberDateFormat extends NumberFormat {

private static final long serialVersionUID = -4334084585068547470L;
final private DateFormat dateFormat;

/**
* Constructs a {@link NumberDateFormat} object using the given {@link DateFormat}.
*
* @param dateFormat {@link DateFormat} used to parse and format dates
*/
public NumberDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}

@Override
public StringBuffer format(double number, StringBuffer toAppendTo,
FieldPosition pos) {
return dateFormat.format(new Date((long) number), toAppendTo, pos);
}

@Override
public StringBuffer format(long number, StringBuffer toAppendTo,
FieldPosition pos) {
return dateFormat.format(new Date(number), toAppendTo, pos);
}

@Override
public Number parse(String source, ParsePosition parsePosition) {
final Date date = dateFormat.parse(source, parsePosition);
return (date == null) ? null : date.getTime();
}

@Override
public StringBuffer format(Object number, StringBuffer toAppendTo,
FieldPosition pos) {
return dateFormat.format(number, toAppendTo, pos);
}

public DateFormat getFormatter() {
return dateFormat;
}

}

/**
* Internal class that allows us to accept '*' (lucene's way of saying 'anything')
Expand All @@ -259,9 +307,11 @@ private class MaxNumberFormat extends NumberFormat {
private static final long serialVersionUID = -407706279343648005L;
private NumberFormat parser = null;
private Number max = null;
private DateMathParser dParser = new DateMathParser(UTC);

public MaxNumberFormat(Number max) {
this(NumberFormat.getNumberInstance(Locale.US), max);

}
public MaxNumberFormat(NumberFormat parser, Number max) {
this.parser = parser;
Expand All @@ -285,6 +335,15 @@ public Number parse(String source, ParsePosition parsePosition) {
parsePosition.setIndex(1);
return max;
}
// it might be a symbolic date math
try {
Date date = dParser.parseMath(null, source);
DateFormat formatter = ((NumberDateFormat) parser).getFormatter();
source = formatter.format(date);
} catch (SolrException e) {
// pass
}

return parser.parse(source, parsePosition);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import monty.solr.util.MontySolrQueryTestCase;
import monty.solr.util.MontySolrSetup;

import org.apache.lucene.queries.mlt.MoreLikeThisQuery;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -86,6 +87,22 @@ public void test() throws Exception {
// test the query parser does the right thing
//setDebug(true);

// added symbolic date math parsing
assertQueryEquals(req("defType", "aqp", "q", "date:[\"1976-12-30T00:30:00Z\" TO \"1977-12-30T00:30:00Z\"]"),
"date:[220753800000 TO 252289800000]",
LegacyNumericRangeQuery.class);
assertQueryEquals(req("defType", "aqp", "q", "date:[\"1976-12-30T00:30:00Z\" TO \"1976-12-30T00:30:00Z+1YEAR\"]"),
"date:[220753800000 TO 252289800000]",
LegacyNumericRangeQuery.class);

// will become: 1972-05-21T17:33:18.772Z
assertQueryEquals(req("defType", "aqp", "q", "date:\"1972-05-20T17:33:18.772Z+1DAY\""),
"date:[75317598000 TO 75317598000]",
LegacyNumericRangeQuery.class);
assertQueryEquals(req("defType", "aqp", "q", "date:\"1972-05-21T17:33:18.772Z\""),
"date:[75317598000 TO 75317598000]",
LegacyNumericRangeQuery.class);

// 2012-01-01T00:00:00 - 2012-02-01T00:00:00 (excl)
assertQueryEquals(req("q", "pubdate:2012-01", "defType", "aqp"),
"date:[1325376000000 TO 1328054400000}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ public void testSpecialCases() throws Exception {
"title", "title bitle"));
assertU(commit("waitSearcher", "true"));


// similar()
assertQueryEquals(req("defType", "aqp", "q", "similar(foo bar baz, input)"),
"like:foo bar baz",
Expand Down

0 comments on commit 4a8f2eb

Please sign in to comment.