SOLR-7010: Remove facet.date client functionality

This commit is contained in:
Steve Rowe 2016-03-03 14:34:45 -05:00
parent 6de2b7dbd1
commit d0279b8d5f
16 changed files with 99 additions and 687 deletions

View File

@ -384,6 +384,8 @@ Other Changes
* SOLR-8725: Allow hyphen in collection, core, shard, and alias name as the non-first character (Anshum Gupta)
* SOLR-7010: Remove facet.date client functionality. (Steve Rowe)
================== 5.5.1 ==================
Bug Fixes

View File

@ -1,255 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.handler.component;
import java.io.IOException;
import java.util.Date;
import java.util.EnumSet;
import java.util.Set;
import org.apache.lucene.search.Query;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.FacetParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.request.SimpleFacets;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.search.DocSet;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.util.DateMathParser;
import org.apache.solr.util.DateFormatUtil;
/**
* Process date facets
*
* @deprecated the whole date faceting feature is deprecated. Use range facets instead which can
* already work with dates.
*/
@Deprecated
public class DateFacetProcessor extends SimpleFacets {
public DateFacetProcessor(SolrQueryRequest req, DocSet docs, SolrParams params, ResponseBuilder rb) {
super(req, docs, params, rb);
}
/**
* @deprecated Use getFacetRangeCounts which is more generalized
*/
@Deprecated
public void getFacetDateCounts(String dateFacet, NamedList<Object> resOuter)
throws IOException {
final IndexSchema schema = searcher.getSchema();
ParsedParams parsed = null;
try {
parsed = parseParams(FacetParams.FACET_DATE, dateFacet);
} catch (SyntaxError syntaxError) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, syntaxError);
}
final SolrParams params = parsed.params;
final SolrParams required = parsed.required;
final String key = parsed.key;
final String f = parsed.facetValue;
final NamedList<Object> resInner = new SimpleOrderedMap<>();
resOuter.add(key, resInner);
final SchemaField sf = schema.getField(f);
if (!(sf.getType() instanceof TrieDateField)) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"Can not date facet on a field which is not a TrieDateField: " + f);
}
final String startS
= required.getFieldParam(f, FacetParams.FACET_DATE_START);
final Date start;
try {
start = DateFormatUtil.parseMath(null, startS);
} catch (SolrException e) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"date facet 'start' is not a valid Date string: " + startS, e);
}
final String endS
= required.getFieldParam(f, FacetParams.FACET_DATE_END);
Date end; // not final, hardend may change this
try {
end = DateFormatUtil.parseMath(null, endS);
} catch (SolrException e) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"date facet 'end' is not a valid Date string: " + endS, e);
}
if (end.before(start)) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"date facet 'end' comes before 'start': " + endS + " < " + startS);
}
final String gap = required.getFieldParam(f, FacetParams.FACET_DATE_GAP);
final DateMathParser dmp = new DateMathParser();
final int minCount = params.getFieldInt(f, FacetParams.FACET_MINCOUNT, 0);
String[] iStrs = params.getFieldParams(f, FacetParams.FACET_DATE_INCLUDE);
// Legacy support for default of [lower,upper,edge] for date faceting
// this is not handled by FacetRangeInclude.parseParam because
// range faceting has differnet defaults
final EnumSet<FacetParams.FacetRangeInclude> include =
(null == iStrs || 0 == iStrs.length) ?
EnumSet.of(FacetParams.FacetRangeInclude.LOWER,
FacetParams.FacetRangeInclude.UPPER,
FacetParams.FacetRangeInclude.EDGE)
: FacetParams.FacetRangeInclude.parseParam(iStrs);
try {
Date low = start;
while (low.before(end)) {
dmp.setNow(low);
String label = DateFormatUtil.formatExternal(low);
Date high = dmp.parseMath(gap);
if (end.before(high)) {
if (params.getFieldBool(f, FacetParams.FACET_DATE_HARD_END, false)) {
high = end;
} else {
end = high;
}
}
if (high.before(low)) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"date facet infinite loop (is gap negative?)");
}
if (high.equals(low)) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"date facet infinite loop: gap is effectively zero");
}
final boolean includeLower =
(include.contains(FacetParams.FacetRangeInclude.LOWER) ||
(include.contains(FacetParams.FacetRangeInclude.EDGE) && low.equals(start)));
final boolean includeUpper =
(include.contains(FacetParams.FacetRangeInclude.UPPER) ||
(include.contains(FacetParams.FacetRangeInclude.EDGE) && high.equals(end)));
final int count = rangeCount(parsed, sf, low, high, includeLower, includeUpper);
if (count >= minCount) {
resInner.add(label, count);
}
low = high;
}
} catch (java.text.ParseException e) {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"date facet 'gap' is not a valid Date Math string: " + gap, e);
}
// explicitly return the gap and end so all the counts
// (including before/after/between) are meaningful - even if mincount
// has removed the neighboring ranges
resInner.add("gap", gap);
resInner.add("start", start);
resInner.add("end", end);
final String[] othersP =
params.getFieldParams(f, FacetParams.FACET_DATE_OTHER);
if (null != othersP && 0 < othersP.length) {
final Set<FacetParams.FacetRangeOther> others = EnumSet.noneOf(FacetParams.FacetRangeOther.class);
for (final String o : othersP) {
others.add(FacetParams.FacetRangeOther.get(o));
}
// no matter what other values are listed, we don't do
// anything if "none" is specified.
if (!others.contains(FacetParams.FacetRangeOther.NONE)) {
boolean all = others.contains(FacetParams.FacetRangeOther.ALL);
if (all || others.contains(FacetParams.FacetRangeOther.BEFORE)) {
// include upper bound if "outer" or if first gap doesn't already include it
resInner.add(FacetParams.FacetRangeOther.BEFORE.toString(),
rangeCount(parsed, sf, null, start,
false,
(include.contains(FacetParams.FacetRangeInclude.OUTER) ||
(!(include.contains(FacetParams.FacetRangeInclude.LOWER) ||
include.contains(FacetParams.FacetRangeInclude.EDGE))))));
}
if (all || others.contains(FacetParams.FacetRangeOther.AFTER)) {
// include lower bound if "outer" or if last gap doesn't already include it
resInner.add(FacetParams.FacetRangeOther.AFTER.toString(),
rangeCount(parsed, sf, end, null,
(include.contains(FacetParams.FacetRangeInclude.OUTER) ||
(!(include.contains(FacetParams.FacetRangeInclude.UPPER) ||
include.contains(FacetParams.FacetRangeInclude.EDGE)))),
false));
}
if (all || others.contains(FacetParams.FacetRangeOther.BETWEEN)) {
resInner.add(FacetParams.FacetRangeOther.BETWEEN.toString(),
rangeCount(parsed, sf, start, end,
(include.contains(FacetParams.FacetRangeInclude.LOWER) ||
include.contains(FacetParams.FacetRangeInclude.EDGE)),
(include.contains(FacetParams.FacetRangeInclude.UPPER) ||
include.contains(FacetParams.FacetRangeInclude.EDGE))));
}
}
}
}
/**
* Returns a list of value constraints and the associated facet counts
* for each facet date field, range, and interval specified in the
* SolrParams
*
* @see FacetParams#FACET_DATE
* @deprecated Use getFacetRangeCounts which is more generalized
*/
@Deprecated
public NamedList<Object> getFacetDateCounts()
throws IOException {
final NamedList<Object> resOuter = new SimpleOrderedMap<>();
final String[] fields = global.getParams(FacetParams.FACET_DATE);
if (null == fields || 0 == fields.length) return resOuter;
for (String f : fields) {
getFacetDateCounts(f, resOuter);
}
return resOuter;
}
/**
* @deprecated Use rangeCount(SchemaField,String,String,boolean,boolean) which is more generalized
*/
@Deprecated
protected int rangeCount(ParsedParams parsed, SchemaField sf, Date low, Date high,
boolean iLow, boolean iHigh) throws IOException {
String lowStr = (low == null) ? null : DateFormatUtil.formatExternal(low);
String highStr = (high == null) ? null : DateFormatUtil.formatExternal(high);
Query rangeQ = sf.getType().getRangeQuery(null, sf, lowStr, highStr, iLow, iHigh);
return searcher.numDocs(rangeQ, parsed.docs);
}
}

View File

@ -66,7 +66,6 @@ public class FacetComponent extends SearchComponent {
public static final String FACET_QUERY_KEY = "facet_queries";
public static final String FACET_FIELD_KEY = "facet_fields";
public static final String FACET_DATE_KEY = "facet_dates";
public static final String FACET_RANGES_KEY = "facet_ranges";
public static final String FACET_INTERVALS_KEY = "facet_intervals";
@ -275,7 +274,6 @@ public class FacetComponent extends SearchComponent {
*
* @see SimpleFacets#getFacetQueryCounts
* @see SimpleFacets#getFacetFieldCounts
* @see DateFacetProcessor#getFacetDateCounts
* @see RangeFacetProcessor#getFacetRangeCounts
* @see RangeFacetProcessor#getFacetIntervalCounts
* @see FacetParams#FACET
@ -286,13 +284,11 @@ public class FacetComponent extends SearchComponent {
if (!simpleFacets.getGlobalParams().getBool(FacetParams.FACET, true))
return null;
DateFacetProcessor dateFacetProcessor = new DateFacetProcessor(simpleFacets.getRequest(), simpleFacets.getDocsOrig(), simpleFacets.getGlobalParams(), simpleFacets.getResponseBuilder());
RangeFacetProcessor rangeFacetProcessor = new RangeFacetProcessor(simpleFacets.getRequest(), simpleFacets.getDocsOrig(), simpleFacets.getGlobalParams(), simpleFacets.getResponseBuilder());
NamedList<Object> counts = new SimpleOrderedMap<>();
try {
counts.add(FACET_QUERY_KEY, simpleFacets.getFacetQueryCounts());
counts.add(FACET_FIELD_KEY, simpleFacets.getFacetFieldCounts());
counts.add(FACET_DATE_KEY, dateFacetProcessor.getFacetDateCounts());
counts.add(FACET_RANGES_KEY, rangeFacetProcessor.getFacetRangeCounts());
counts.add(FACET_INTERVALS_KEY, simpleFacets.getFacetIntervalCounts());
counts.add(SpatialHeatmapFacets.RESPONSE_KEY, simpleFacets.getHeatmapCounts());
@ -713,9 +709,6 @@ public class FacetComponent extends SearchComponent {
}
}
// Distributed facet_dates
doDistribDates(fi, facet_counts);
// Distributed facet_ranges
@SuppressWarnings("unchecked")
SimpleOrderedMap<SimpleOrderedMap<Object>> rangesFromShard = (SimpleOrderedMap<SimpleOrderedMap<Object>>)
@ -929,53 +922,6 @@ public class FacetComponent extends SearchComponent {
}
}
//
// The implementation below uses the first encountered shard's
// facet_dates as the basis for subsequent shards' data to be merged.
// (the "NOW" param should ensure consistency)
private void doDistribDates(FacetInfo fi, NamedList facet_counts) {
@SuppressWarnings("unchecked")
SimpleOrderedMap<SimpleOrderedMap<Object>> facet_dates =
(SimpleOrderedMap<SimpleOrderedMap<Object>>)
facet_counts.get("facet_dates");
if (facet_dates != null) {
// go through each facet_date
for (Map.Entry<String,SimpleOrderedMap<Object>> entry : facet_dates) {
final String field = entry.getKey();
if (fi.dateFacets.get(field) == null) {
// first time we've seen this field, no merging
fi.dateFacets.add(field, entry.getValue());
} else {
// not the first time, merge current field
SimpleOrderedMap<Object> shardFieldValues
= entry.getValue();
SimpleOrderedMap<Object> existFieldValues
= fi.dateFacets.get(field);
for (Map.Entry<String,Object> existPair : existFieldValues) {
final String key = existPair.getKey();
if (key.equals("gap") ||
key.equals("end") ||
key.equals("start")) {
// we can skip these, must all be the same across shards
continue;
}
// can be null if inconsistencies in shards responses
Integer newValue = (Integer) shardFieldValues.get(key);
if (null != newValue) {
Integer oldValue = ((Integer) existPair.getValue());
existPair.setValue(oldValue + newValue);
}
}
}
}
}
}
private void doDistribPivots(ResponseBuilder rb, int shardNum, NamedList facet_counts) {
@SuppressWarnings("unchecked")
SimpleOrderedMap<List<NamedList<Object>>> facet_pivot
@ -1159,8 +1105,6 @@ public class FacetComponent extends SearchComponent {
}
}
facet_counts.add("facet_dates", fi.dateFacets);
SimpleOrderedMap<SimpleOrderedMap<Object>> rangeFacetOutput = new SimpleOrderedMap<>();
for (Map.Entry<String, RangeFacetRequest.DistribRangeFacet> entry : fi.rangeFacets.entrySet()) {
String key = entry.getKey();

View File

@ -281,18 +281,6 @@ public class SimpleFacets {
}
}
/**
* Looks at various Params to determining if any simple Facet Constraint count
* computations are desired.
*
* @return a NamedList of Facet Count info or null
* @deprecated use {@link org.apache.solr.handler.component.FacetComponent#getFacetCounts(SimpleFacets)} instead
*/
@Deprecated
public NamedList<Object> getFacetCounts() {
return FacetComponent.getFacetCounts(this);
}
/**
* Returns a list of facet counts for each of the facet queries
* specified in the params

View File

@ -225,27 +225,6 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
String facetQuery = "id:[1 TO 15]";
// simple date facet on one field
query("q",facetQuery, "rows",100, "facet","true",
"facet.date",tdate_a,
"facet.date",tdate_a,
"facet.date.other", "all",
"facet.date.start","2010-05-01T11:00:00Z",
"facet.date.gap","+1DAY",
"facet.date.end","2010-05-20T11:00:00Z");
// date facet on multiple fields
query("q",facetQuery, "rows",100, "facet","true",
"facet.date",tdate_a,
"facet.date",tdate_b,
"facet.date",tdate_a,
"facet.date.other", "all",
"f."+tdate_b+".facet.date.start","2009-05-01T11:00:00Z",
"f."+tdate_b+".facet.date.gap","+3MONTHS",
"facet.date.start","2010-05-01T11:00:00Z",
"facet.date.gap","+1DAY",
"facet.date.end","2010-05-20T11:00:00Z");
// simple range facet on one field
query("q",facetQuery, "rows",100, "facet","true",
"facet.range",tlong,

View File

@ -57,7 +57,7 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
public static final String FOO_STRING_FIELD = "foo_s1";
public static final String SMALL_STRING_FIELD = "small_s1";
public static final String SMALL_INT_FIELD = "small_i";
static final String EMPTY_FACETS = "'facet_dates':{},'facet_ranges':{},'facet_intervals':{},'facet_heatmaps':{}";
static final String EMPTY_FACETS = "'facet_ranges':{},'facet_intervals':{},'facet_heatmaps':{}";
@BeforeClass
public static void beforeTests() throws Exception {

View File

@ -249,11 +249,7 @@ public class TestTrie extends SolrTestCaseJ4 {
"facet.field", "tint",
"facet.field", "tlong",
"facet.field", "tfloat",
"facet.field", "tdouble",
"facet.date", "tdate",
"facet.date.start", "NOW/DAY",
"facet.date.end", "NOW/DAY+6DAYS",
"facet.date.gap", "+1DAY");
"facet.field", "tdouble");
testFacetField(req, "tint", "0", "2");
testFacetField(req, "tint", "5", "1");
testFacetField(req, "tlong", String.valueOf(Integer.MAX_VALUE), "2");
@ -262,9 +258,6 @@ public class TestTrie extends SolrTestCaseJ4 {
testFacetField(req, "tfloat", String.valueOf(5*5*31.11f), "1");
testFacetField(req, "tdouble", String.valueOf(2.33d), "2");
testFacetField(req, "tdouble", String.valueOf(5*2.33d), "1");
testFacetDate(req, "tdate", format.format(dmp.parseMath("/DAY")), "4");
testFacetDate(req, "tdate", format.format(dmp.parseMath("/DAY+5DAYS")), "2");
}
private void checkPrecisionSteps(String fieldType) {
@ -279,9 +272,4 @@ public class TestTrie extends SolrTestCaseJ4 {
String xpath = "//lst[@name='facet_fields']/lst[@name='" + field + "']/int[@name='" + value + "'][.='" + count + "']";
assertQ(req, xpath);
}
private void testFacetDate(SolrQueryRequest req, String field, String value, String count) {
String xpath = "//lst[@name='facet_dates']/lst[@name='" + field + "']/int[@name='" + value + "'][.='" + count + "']";
assertQ(req, xpath);
}
}

View File

@ -804,46 +804,33 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
add_doc(i, "2014", f, "1976-07-05T22:22:22.222Z");
}
@Test
public void testTrieDateFacets() {
helpTestDateFacets("bday", false, FacetRangeMethod.FILTER);
}
@Test
public void testTrieDateRangeFacets() {
helpTestDateFacets("bday", true, FacetRangeMethod.FILTER);
helpTestDateFacets("bday", FacetRangeMethod.FILTER);
}
@Test
public void testTrieDateFacetsDocValues() {
helpTestDateFacets("bday", false, FacetRangeMethod.DV);
}
@Test
public void testTrieDateRangeFacetsDocValues() {
helpTestDateFacets("bday", true, FacetRangeMethod.DV);
helpTestDateFacets("bday", FacetRangeMethod.DV);
}
@Test
public void testDateRangeFieldFacets() {
helpTestDateFacets("bday_drf", true, FacetRangeMethod.FILTER);
helpTestDateFacets("bday_drf", FacetRangeMethod.FILTER);
}
private void helpTestDateFacets(final String fieldName,
final boolean rangeMode,
final FacetRangeMethod rangeFacetMethod) {
final String p = rangeMode ? "facet.range" : "facet.date";
final String b = rangeMode ? "facet_ranges" : "facet_dates";
private void helpTestDateFacets(final String fieldName, final FacetRangeMethod rangeFacetMethod) {
final String p = "facet.range";
final String b = "facet_ranges";
final String f = fieldName;
final String c = (rangeMode ? "/lst[@name='counts']" : "");
final String c = "/lst[@name='counts']";
final String pre = "//lst[@name='"+b+"']/lst[@name='"+f+"']" + c;
final String meta = pre + (rangeMode ? "/../" : "");
final String meta = pre + "/../";
// date faceting defaults to include both endpoints,
// range faceting defaults to including only lower
// range faceting defaults to including only lower endpoint
// doc exists with value @ 00:00:00.000 on July5
final String jul4 = rangeMode ? "[.='1' ]" : "[.='2' ]";
final String jul4 = "[.='1' ]";
assertQ("check counts for month of facet by day",
req( "q", "*:*"
@ -856,7 +843,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".other", "all"
,p+".method", rangeFacetMethod.toString() //This only applies to range faceting, won't be use for date faceting
)
,"*[count("+pre+"/int)="+(rangeMode ? 31 : 34)+"]"
,"*[count("+pre+"/int)=31]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
@ -905,7 +892,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".other", "all"
,"facet.mincount", "1"
)
,"*[count("+pre+"/int)="+(rangeMode ? 8 : 11)+"]"
,"*[count("+pre+"/int)=8]"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
,pre+"/int[@name='1976-07-04T00:00:00Z']" + jul4
,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
@ -930,9 +917,9 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".other", "all"
,"f." + f + ".facet.mincount", "2"
)
,"*[count("+pre+"/int)="+(rangeMode ? 3 : 7)+"]"
,"*[count("+pre+"/int)=3]"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
,pre+(rangeMode ? "" : "/int[@name='1976-07-04T00:00:00Z']" +jul4)
,pre
,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
,pre+"/int[@name='1976-07-15T00:00:00Z'][.='2' ]"
,meta+"/int[@name='before' ][.='2']"
@ -950,7 +937,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".gap", "+1DAY"
,p+".other", "all"
)
,"*[count("+pre+"/int)="+(rangeMode ? 2 : 5)+"]"
,"*[count("+pre+"/int)=2]"
,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
@ -966,11 +953,11 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".gap", "+1DAY"
,p+".other", "all"
)
,"*[count("+pre+"/int)="+(rangeMode ? 2 : 5)+"]"
,"*[count("+pre+"/int)=2]"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
,pre+"/int[@name='1976-07-04T00:00:00Z']" + jul4
,meta+"/int[@name='after' ][.='"+(rangeMode ? 9 : 8)+"']"
,meta+"/int[@name='after' ][.='9']"
);
@ -985,7 +972,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".other", "all"
,p+".hardend","false"
)
,"*[count("+pre+"/int)="+(rangeMode ? 3 : 6)+"]"
,"*[count("+pre+"/int)=3]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='5' ]"
,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0' ]"
,pre+"/int[@name='1976-07-11T00:00:00Z'][.='4' ]"
@ -1006,7 +993,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".other", "all"
,p+".hardend","true"
)
,"*[count("+pre+"/int)="+(rangeMode ? 3 : 6)+"]"
,"*[count("+pre+"/int)=3]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='5' ]"
,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0' ]"
,pre+"/int[@name='1976-07-11T00:00:00Z'][.='1' ]"
@ -1018,31 +1005,25 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
}
@Test
public void testTrieDateFacetsWithIncludeOption() {
helpTestDateFacetsWithIncludeOption("a_tdt", false);
}
@Test
public void testTrieDateRangeFacetsWithIncludeOption() {
helpTestDateFacetsWithIncludeOption("a_tdt", true);
helpTestDateRangeFacetsWithIncludeOption("a_tdt");
}
@Test
public void testDateRangeFieldDateRangeFacetsWithIncludeOption() {
helpTestDateFacetsWithIncludeOption("a_drf", true);
helpTestDateRangeFacetsWithIncludeOption("a_drf");
}
/** Similar to helpTestDateFacets, but for different fields with test data
exactly on boundary marks */
private void helpTestDateFacetsWithIncludeOption(final String fieldName,
final boolean rangeMode) {
final String p = rangeMode ? "facet.range" : "facet.date";
final String b = rangeMode ? "facet_ranges" : "facet_dates";
private void helpTestDateRangeFacetsWithIncludeOption(final String fieldName) {
final String p = "facet.range";
final String b = "facet_ranges";
final String f = fieldName;
final String c = (rangeMode ? "/lst[@name='counts']" : "");
final String c = "/lst[@name='counts']";
final String pre = "//lst[@name='"+b+"']/lst[@name='"+f+"']" + c;
final String meta = pre + (rangeMode ? "/../" : "");
final String meta = pre + "/../";
assertQ("checking counts for lower",
req( "q", "*:*"
@ -1056,7 +1037,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "lower"
)
// 15 days + pre+post+inner = 18
,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
,"*[count("+pre+"/int)=15]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='0']"
@ -1090,7 +1071,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "upper"
)
// 15 days + pre+post+inner = 18
,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
,"*[count("+pre+"/int)=15]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='1' ]"
@ -1125,7 +1106,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "upper"
)
// 15 days + pre+post+inner = 18
,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
,"*[count("+pre+"/int)=15]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='1' ]"
@ -1160,7 +1141,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "edge"
)
// 15 days + pre+post+inner = 18
,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
,"*[count("+pre+"/int)=15]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='1' ]"
@ -1195,7 +1176,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "outer"
)
// 12 days + pre+post+inner = 15
,"*[count("+pre+"/int)="+(rangeMode ? 12 : 15)+"]"
,"*[count("+pre+"/int)=12]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='1' ]"
@ -1227,7 +1208,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "edge"
)
// 12 days + pre+post+inner = 15
,"*[count("+pre+"/int)="+(rangeMode ? 12 : 15)+"]"
,"*[count("+pre+"/int)=12]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='0']"
@ -1259,7 +1240,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "outer"
)
// 12 days + pre+post+inner = 15
,"*[count("+pre+"/int)="+(rangeMode ? 12 : 15)+"]"
,"*[count("+pre+"/int)=12]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='0']"
@ -1292,7 +1273,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "outer"
)
// 12 days + pre+post+inner = 15
,"*[count("+pre+"/int)="+(rangeMode ? 12 : 15)+"]"
,"*[count("+pre+"/int)=12]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='0']"
@ -1323,7 +1304,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "all"
)
// 12 days + pre+post+inner = 15
,"*[count("+pre+"/int)="+(rangeMode ? 12 : 15)+"]"
,"*[count("+pre+"/int)=12]"
,pre+"/int[@name='1976-07-01T00:00:00Z'][.='1' ]"
,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T00:00:00Z'][.='1' ]"
@ -1344,20 +1325,17 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
}
@Test
public void testDateFacetsWithTz() {
for (boolean rangeType : new boolean[] { true, false }) {
helpTestDateFacetsWithTz("a_tdt", rangeType);
}
public void testDateRangeFacetsWithTz() {
helpTestDateRangeFacetsWithTz("a_tdt");
}
private void helpTestDateFacetsWithTz(final String fieldName,
final boolean rangeMode) {
final String p = rangeMode ? "facet.range" : "facet.date";
final String b = rangeMode ? "facet_ranges" : "facet_dates";
private void helpTestDateRangeFacetsWithTz(final String fieldName) {
final String p = "facet.range";
final String b = "facet_ranges";
final String f = fieldName;
final String c = (rangeMode ? "/lst[@name='counts']" : "");
final String c = "/lst[@name='counts']";
final String pre = "//lst[@name='"+b+"']/lst[@name='"+f+"']" + c;
final String meta = pre + (rangeMode ? "/../" : "");
final String meta = pre + "/../";
final String TZ = "America/Los_Angeles";
assumeTrue("Test requires JVM to know about about TZ: " + TZ,
@ -1377,7 +1355,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "lower"
)
// 15 days + pre+post+inner = 18
,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
,"*[count("+pre+"/int)=15]"
,pre+"/int[@name='1976-07-01T07:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-02T07:00:00Z'][.='0']"
,pre+"/int[@name='1976-07-03T07:00:00Z'][.='1' ]"
@ -1415,7 +1393,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
,p+".include", "lower"
)
// 15 days + pre+post+inner = 18
,"*[count("+pre+"/int)="+(rangeMode ? 15 : 18)+"]"
,"*[count("+pre+"/int)=15]"
,pre+"/int[@name='2010-11-01T07:00:00Z'][.='0']"
,pre+"/int[@name='2010-11-02T07:00:00Z'][.='0']"
,pre+"/int[@name='2010-11-03T07:00:00Z'][.='0']"
@ -2388,16 +2366,14 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
400);
}
String field = "foo_dt";
for (String type : new String[]{"date", "range"}) {
assertQEx("no zero gap error for facet." + type + ": " + field,
assertQEx("no zero gap error for facet.range: " + field,
req("q", "*:*",
"facet", "true",
"facet." + type, field,
"facet."+type+".start", "NOW",
"facet."+type+".gap", "+0DAYS",
"facet."+type+".end", "NOW+10DAY"),
"facet.range", field,
"facet.range.start", "NOW",
"facet.range.gap", "+0DAYS",
"facet.range.end", "NOW+10DAY"),
400);
}
field = "foo_f";
assertQEx("no float underflow error: " + field,
req("q", "*:*",

View File

@ -323,103 +323,6 @@ public class TestFaceting extends SolrTestCaseJ4 {
}
@Test
public void testDateFacetsWithMultipleConfigurationForSameField() {
clearIndex();
final String f = "bday_dt";
assertU(adoc("id", "1", f, "1976-07-04T12:08:56.235Z"));
assertU(adoc("id", "2", f, "1976-07-05T00:00:00.000Z"));
assertU(adoc("id", "3", f, "1976-07-15T00:07:67.890Z"));
assertU(commit());
assertU(adoc("id", "4", f, "1976-07-21T00:07:67.890Z"));
assertU(adoc("id", "5", f, "1976-07-13T12:12:25.255Z"));
assertU(adoc("id", "6", f, "1976-07-03T17:01:23.456Z"));
assertU(adoc("id", "7", f, "1976-07-12T12:12:25.255Z"));
assertU(adoc("id", "8", f, "1976-07-15T15:15:15.155Z"));
assertU(adoc("id", "9", f, "1907-07-12T13:13:23.235Z"));
assertU(adoc("id", "10", f, "1976-07-03T11:02:45.678Z"));
assertU(commit());
assertU(adoc("id", "11", f, "1907-07-12T12:12:25.255Z"));
assertU(adoc("id", "12", f, "2007-07-30T07:07:07.070Z"));
assertU(adoc("id", "13", f, "1976-07-30T22:22:22.222Z"));
assertU(adoc("id", "14", f, "1976-07-05T22:22:22.222Z"));
assertU(commit());
final String preFoo = "//lst[@name='facet_dates']/lst[@name='foo']";
final String preBar = "//lst[@name='facet_dates']/lst[@name='bar']";
assertQ("check counts for month of facet by day",
req( "q", "*:*"
,"rows", "0"
,"facet", "true"
,"facet.date", "{!key=foo " +
"facet.date.start=1976-07-01T00:00:00.000Z " +
"facet.date.end=1976-07-01T00:00:00.000Z+1MONTH " +
"facet.date.gap=+1DAY " +
"facet.date.other=all " +
"}" + f
,"facet.date", "{!key=bar " +
"facet.date.start=1976-07-01T00:00:00.000Z " +
"facet.date.end=1976-07-01T00:00:00.000Z+7DAY " +
"facet.date.gap=+1DAY " +
"}" + f
)
// 31 days + pre+post+inner = 34
,"*[count("+preFoo+"/int)=34]"
,preFoo+"/int[@name='1976-07-01T00:00:00Z'][.='0' ]"
,preFoo+"/int[@name='1976-07-02T00:00:00Z'][.='0' ]"
,preFoo+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
// july4th = 2 because exists doc @ 00:00:00.000 on July5
// (date faceting is inclusive)
,preFoo+"/int[@name='1976-07-04T00:00:00Z'][.='2' ]"
,preFoo+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
,preFoo+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-07T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
,preFoo+"/int[@name='1976-07-13T00:00:00Z'][.='1' ]"
,preFoo+"/int[@name='1976-07-14T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-15T00:00:00Z'][.='2' ]"
,preFoo+"/int[@name='1976-07-16T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-17T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-18T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-19T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-21T00:00:00Z'][.='1' ]"
,preFoo+"/int[@name='1976-07-22T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-23T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-24T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-25T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-26T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-27T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-28T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-29T00:00:00Z'][.='0']"
,preFoo+"/int[@name='1976-07-30T00:00:00Z'][.='1' ]"
,preFoo+"/int[@name='1976-07-31T00:00:00Z'][.='0']"
,preFoo+"/int[@name='before' ][.='2']"
,preFoo+"/int[@name='after' ][.='1']"
,preFoo+"/int[@name='between'][.='11']"
,"*[count("+preBar+"/int)=7]"
,preBar+"/int[@name='1976-07-01T00:00:00Z'][.='0' ]"
,preBar+"/int[@name='1976-07-02T00:00:00Z'][.='0' ]"
,preBar+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
// july4th = 2 because exists doc @ 00:00:00.000 on July5
// (date faceting is inclusive)
,preBar+"/int[@name='1976-07-04T00:00:00Z'][.='2' ]"
,preBar+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
,preBar+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
,preBar+"/int[@name='1976-07-07T00:00:00Z'][.='0']"
);
clearIndex();
assertU(commit());
}
public void testSimpleFacetCountsWithMultipleConfigurationsForSameField() {
clearIndex();
String fname = "trait_ss";

View File

@ -439,7 +439,6 @@ In your terminal, you'll see:
"uk",1,
"viewsonic",1,
"samsung",0]},
"facet_dates":{},
"facet_ranges":{},
"facet_intervals":{}}}
@ -482,7 +481,6 @@ In your terminal you will see:
"facet_counts":{
"facet_queries":{},
"facet_fields":{},
"facet_dates":{},
"facet_ranges":{
"price":{
"counts":[

View File

@ -86,38 +86,12 @@ import org.apache.solr.client.solrj.util.ClientUtils;
private String _name = null;
private List<Count> _values = null;
private String _gap = null;
private Date _end = null;
public FacetField( final String n )
{
_name = n;
}
public FacetField(String name, String gap, Date end) {
_name = name;
_gap = gap;
_end = end;
}
/**
* Date Gap Facet parameter
*
* @return the value specified for facet.date.gap
*/
public String getGap() {
return _gap;
}
/**
* Date End Facet parameter
*
* @return the value specified for facet.date.end
*/
public Date getEnd() {
return _end;
}
/**
* Insert at the end of the list
*/

View File

@ -332,30 +332,6 @@ public class QueryResponse extends SolrResponseBase
}
}
//Parse date facets
NamedList<NamedList<Object>> df = (NamedList<NamedList<Object>>) info.get("facet_dates");
if (df != null) {
// System.out.println(df);
_facetDates = new ArrayList<>( df.size() );
for (Map.Entry<String, NamedList<Object>> facet : df) {
// System.out.println("Key: " + facet.getKey() + " Value: " + facet.getValue());
NamedList<Object> values = facet.getValue();
String gap = (String) values.get("gap");
Date end = (Date) values.get("end");
FacetField f = new FacetField(facet.getKey(), gap, end);
for (Map.Entry<String, Object> entry : values) {
try {
f.add(entry.getKey(), Long.parseLong(entry.getValue().toString()));
} catch (NumberFormatException e) {
//Ignore for non-number responses which are already handled above
}
}
_facetDates.add(f);
}
}
//Parse range facets
NamedList<NamedList<Object>> rf = (NamedList<NamedList<Object>>) info.get("facet_ranges");
if (rf != null) {

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">0</int>
<lst name="params">
<str name="facet.date.start">NOW/DAY-5DAYS</str>
<str name="facet">true</str>
<str name="facet.date.hardend">true</str>
<str name="q">*:*</str>
<arr name="facet.date">
<str>timestamp</str>
<str>timestamp2</str>
</arr>
<str name="facet.date.gap">+1DAY</str>
<str name="facet.date.other">ALL</str>
<str name="facet.date.end">NOW/DAY+1DAY</str>
<str name="rows">0</str>
</lst>
</lst>
<result name="response" numFound="16" start="0"/>
<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields"/>
<lst name="facet_dates">
<lst name="timestamp">
<int name="2008-03-06T00:00:00.000Z">0</int>
<int name="2008-03-07T00:00:00.000Z">0</int>
<int name="2008-03-08T00:00:00.000Z">0</int>
<int name="2008-03-09T00:00:00.000Z">0</int>
<int name="2008-03-10T00:00:00.000Z">0</int>
<int name="2008-03-11T00:00:00.000Z">0</int>
<str name="gap">+1DAY</str>
<date name="end">2008-03-12T00:00:00Z</date>
<int name="before">16</int>
<int name="after">0</int>
<int name="between">0</int>
</lst>
<lst name="timestamp2">
<int name="2008-03-06T00:00:00.000Z">0</int>
<int name="2008-03-07T00:00:00.000Z">0</int>
<int name="2008-03-08T00:00:00.000Z">0</int>
<int name="2008-03-09T00:00:00.000Z">0</int>
<int name="2008-03-10T00:00:00.000Z">0</int>
<int name="2008-03-11T00:00:00.000Z">0</int>
<str name="gap">+1DAY</str>
<date name="end">2008-03-12T00:00:00Z</date>
<int name="before">0</int>
<int name="after">0</int>
<int name="between">0</int>
</lst>
</lst>
<lst name="facet_ranges">
<lst name="price">
<lst name="counts">
<int name="0.0">3</int>
<int name="1.0">0</int>
<int name="2.0">0</int>
<int name="3.0">0</int>
<int name="4.0">0</int>
</lst>
<float name="gap">1.0</float>
<float name="start">0.0</float>
<float name="end">5.0</float>
</lst>
<lst name="manufacturedate_dt">
<lst name="counts">
<int name="2005-02-13T15:26:37Z">4</int>
<int name="2006-02-13T15:26:37Z">7</int>
<int name="2007-02-13T15:26:37Z">0</int>
</lst>
<str name="gap">+1YEAR</str>
<date name="start">2005-02-13T15:26:37Z</date>
<date name="end">2008-02-13T15:26:37Z</date>
<int name="before">90</int>
<int name="after">1</int>
<int name="between">11</int>
</lst>
</lst>
</lst>
</response>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">0</int>
<lst name="params">
<str name="facet">true</str>
<str name="q">*:*</str>
<str name="rows">0</str>
</lst>
</lst>
<result name="response" numFound="16" start="0"/>
<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields"/>
<lst name="facet_ranges">
<lst name="price">
<lst name="counts">
<int name="0.0">3</int>
<int name="1.0">0</int>
<int name="2.0">0</int>
<int name="3.0">0</int>
<int name="4.0">0</int>
</lst>
<float name="gap">1.0</float>
<float name="start">0.0</float>
<float name="end">5.0</float>
</lst>
<lst name="manufacturedate_dt">
<lst name="counts">
<int name="2005-02-13T15:26:37Z">4</int>
<int name="2006-02-13T15:26:37Z">7</int>
<int name="2007-02-13T15:26:37Z">0</int>
</lst>
<str name="gap">+1YEAR</str>
<date name="start">2005-02-13T15:26:37Z</date>
<date name="end">2008-02-13T15:26:37Z</date>
<int name="before">90</int>
<int name="after">1</int>
<int name="between">11</int>
</lst>
</lst>
</lst>
</response>

View File

@ -49,7 +49,7 @@ import org.junit.Test;
public class NoOpResponseParserTest extends SolrJettyTestBase {
private static InputStream getResponse() throws IOException {
return new SolrResourceLoader().openResource("solrj/sampleDateFacetResponse.xml");
return new SolrResourceLoader().openResource("solrj/sampleRangeFacetResponse.xml");
}
@BeforeClass

View File

@ -39,34 +39,10 @@ import org.junit.Test;
*/
@Limit(bytes=20000)
public class QueryResponseTest extends LuceneTestCase {
@Test
public void testDateFacets() throws Exception {
XMLResponseParser parser = new XMLResponseParser();
InputStream is = new SolrResourceLoader().openResource("solrj/sampleDateFacetResponse.xml");
assertNotNull(is);
Reader in = new InputStreamReader(is, StandardCharsets.UTF_8);
NamedList<Object> response = parser.processResponse(in);
in.close();
QueryResponse qr = new QueryResponse(response, null);
Assert.assertNotNull(qr);
Assert.assertNotNull(qr.getFacetDates());
for (FacetField f : qr.getFacetDates()) {
Assert.assertNotNull(f);
// TODO - test values?
// System.out.println(f.toString());
// System.out.println("GAP: " + f.getGap());
// System.out.println("END: " + f.getEnd());
}
}
@Test
public void testRangeFacets() throws Exception {
XMLResponseParser parser = new XMLResponseParser();
InputStream is = new SolrResourceLoader().openResource("solrj/sampleDateFacetResponse.xml");
InputStream is = new SolrResourceLoader().openResource("solrj/sampleRangeFacetResponse.xml");
assertNotNull(is);
Reader in = new InputStreamReader(is, StandardCharsets.UTF_8);
NamedList<Object> response = parser.processResponse(in);