You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2010/05/03 20:21:25 UTC
svn commit: r940556 - in /lucene/dev/trunk/solr: CHANGES.txt
src/common/org/apache/solr/common/params/FacetParams.java
src/java/org/apache/solr/request/SimpleFacets.java
src/test/org/apache/solr/request/SimpleFacetsTest.java
Author: hossman
Date: Mon May 3 18:21:25 2010
New Revision: 940556
URL: http://svn.apache.org/viewvc?rev=940556&view=rev
Log:
SOLR-397: creation of a facet.date.include param for controlling what range endpoints are inclusive when date faceting
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/src/common/org/apache/solr/common/params/FacetParams.java
lucene/dev/trunk/solr/src/java/org/apache/solr/request/SimpleFacets.java
lucene/dev/trunk/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=940556&r1=940555&r2=940556&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Mon May 3 18:21:25 2010
@@ -144,6 +144,14 @@ New Features
supports "percentages" which get evaluated relative the current size of
the cache when warming happens.
(Tomas Fernandez Lobbe and hossman)
+
+* SOLR-397: Date Faceting now supports a "facet.date.include" param
+ for specifying when the upper & lower end points of computed date
+ ranges should be included in the range. Legal values are: "all",
+ "lower", "upper", "edge", and "outer". For backwards compatibility
+ the default value is the set: [lower,upper,edge], so that al ranges
+ between start and ed are inclusive of their endpoints, but the
+ "before" and "after" ranges are not.
Optimizations
----------------------
Modified: lucene/dev/trunk/solr/src/common/org/apache/solr/common/params/FacetParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/common/org/apache/solr/common/params/FacetParams.java?rev=940556&r1=940555&r2=940556&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/common/org/apache/solr/common/params/FacetParams.java (original)
+++ lucene/dev/trunk/solr/src/common/org/apache/solr/common/params/FacetParams.java Mon May 3 18:21:25 2010
@@ -19,6 +19,7 @@ package org.apache.solr.common.params;
import org.apache.solr.common.SolrException;
+import java.util.EnumSet;
/**
* Facet parameters
@@ -165,6 +166,7 @@ public interface FacetParams {
* <li>none = no additional info requested</li>
* </ul>
* @see #FACET_DATE_OTHER
+ * @see #FACET_DATE_INCLUDE
*/
public enum FacetDateOther {
BEFORE, AFTER, BETWEEN, ALL, NONE;
@@ -180,6 +182,73 @@ public interface FacetParams {
}
}
+ /**
+ * <p>
+ * Multivalued string indicating what rules should be applied to determine
+ * when the the ranges generated for date faceting should be inclusive or
+ * exclusive of their end points.
+ * </p>
+ * <p>
+ * The default value if none are specified is: [lower,upper,edge]
+ * </p>
+ * <p>
+ * Can be overriden on a per field basis.
+ * </p>
+ * @see FacetDateInclude
+ */
+ public static final String FACET_DATE_INCLUDE = FACET_DATE + ".include";
+
+ /**
+ * An enumeration of the legal values for FACET_DATE_INCLUDE...
+ * <ul>
+ * <li>lower = all gap based ranges include their lower bound</li>
+ * <li>upper = all gap based ranges include their upper bound</li>
+ * <li>edge = the first and last gap ranges include their edge bounds (ie: lower
+ * for the first one, upper for the last one) even if the corrisponding
+ * upper/lower option is not specified
+ * </li>
+ * <li>outer = the FacetDateOther.BEFORE and FacetDateOther.AFTER ranges
+ * should be inclusive of their bounds, even if the first or last ranges
+ * already include thouse boundaries.
+ * </li>
+ * <li>all = shorthand for lower, upper, edge, and outer</li>
+ * </ul>
+ * @see #FACET_DATE_INCLUDE
+ */
+ public enum FacetDateInclude {
+ ALL, LOWER, UPPER, EDGE, OUTER;
+ public String toString() { return super.toString().toLowerCase(); }
+ public static FacetDateInclude get(String label) {
+ try {
+ return valueOf(label.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new SolrException
+ (SolrException.ErrorCode.BAD_REQUEST,
+ label+" is not a valid type of for "+FACET_DATE_INCLUDE+" information",e);
+ }
+ }
+ /**
+ * Convinience method for parsing the param value according to the correct semantics.
+ */
+ public static EnumSet<FacetDateInclude> parseParam(final String[] param) {
+ // short circut for default behavior
+ if (null == param || 0 == param.length )
+ return EnumSet.of(LOWER, UPPER, EDGE);
+
+ // build up set containing whatever is specified
+ final EnumSet<FacetDateInclude> include = EnumSet.noneOf(FacetDateInclude.class);
+ for (final String o : param) {
+ include.add(FacetDateInclude.get(o));
+ }
+
+ // if set contains all, then we're back to short circuting
+ if (include.contains(FacetDateInclude.ALL))
+ return EnumSet.allOf(FacetDateInclude.class);
+
+ // use whatever we've got.
+ return include;
+ }
+ }
}
Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/request/SimpleFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/request/SimpleFacets.java?rev=940556&r1=940555&r2=940556&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/request/SimpleFacets.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/request/SimpleFacets.java Mon May 3 18:21:25 2010
@@ -29,6 +29,7 @@ import org.apache.solr.common.params.Req
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.FacetParams.FacetDateOther;
+import org.apache.solr.common.params.FacetParams.FacetDateInclude;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils;
@@ -636,8 +637,10 @@ public class SimpleFacets {
int minCount = params.getFieldInt(f,FacetParams.FACET_MINCOUNT, 0);
+ final EnumSet<FacetDateInclude> include = FacetDateInclude.parseParam
+ (params.getFieldParams(f,FacetParams.FACET_DATE_INCLUDE));
+
try {
-
Date low = start;
while (low.before(end)) {
dmp.setNow(low);
@@ -656,7 +659,14 @@ public class SimpleFacets {
(SolrException.ErrorCode.BAD_REQUEST,
"date facet infinite loop (is gap negative?)");
}
- int count = rangeCount(sf,low,high,true,true);
+ boolean includeLower =
+ (include.contains(FacetDateInclude.LOWER) ||
+ (include.contains(FacetDateInclude.EDGE) && low.equals(start)));
+ boolean includeUpper =
+ (include.contains(FacetDateInclude.UPPER) ||
+ (include.contains(FacetDateInclude.EDGE) && high.equals(end)));
+
+ int count = rangeCount(sf,low,high,includeLower,includeUpper);
if (count >= minCount) {
resInner.add(label, count);
}
@@ -687,16 +697,30 @@ public class SimpleFacets {
boolean all = others.contains(FacetDateOther.ALL);
if (all || others.contains(FacetDateOther.BEFORE)) {
+ // include upper bound if "outer" or if first gap doesn't already include it
resInner.add(FacetDateOther.BEFORE.toString(),
- rangeCount(sf,null,start,false,false));
+ rangeCount(sf,null,start,
+ false,
+ (include.contains(FacetDateInclude.OUTER) ||
+ (! (include.contains(FacetDateInclude.LOWER) ||
+ include.contains(FacetDateInclude.EDGE))))));
}
if (all || others.contains(FacetDateOther.AFTER)) {
+ // include lower bound if "outer" or if last gap doesn't already include it
resInner.add(FacetDateOther.AFTER.toString(),
- rangeCount(sf,end,null,false,false));
+ rangeCount(sf,end,null,
+ (include.contains(FacetDateInclude.OUTER) ||
+ (! (include.contains(FacetDateInclude.UPPER) ||
+ include.contains(FacetDateInclude.EDGE)))),
+ false));
}
if (all || others.contains(FacetDateOther.BETWEEN)) {
resInner.add(FacetDateOther.BETWEEN.toString(),
- rangeCount(sf,start,end,true,true));
+ rangeCount(sf,start,end,
+ (include.contains(FacetDateInclude.LOWER) ||
+ include.contains(FacetDateInclude.EDGE)),
+ (include.contains(FacetDateInclude.UPPER) ||
+ include.contains(FacetDateInclude.EDGE))));
}
}
}
Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java?rev=940556&r1=940555&r2=940556&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java Mon May 3 18:21:25 2010
@@ -19,6 +19,7 @@ package org.apache.solr.request;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.BeforeClass;
+import org.junit.After;
import org.junit.Test;
import java.util.ArrayList;
@@ -258,23 +259,26 @@ public class SimpleFacetsTest extends So
}
public static void indexDateFacets() {
+ final String i = "id";
final String f = "bday";
- final String pre = "//lst[@name='facet_dates']/lst[@name='"+f+"']";
-
- add_doc("id", "201", f, "1976-07-04T12:08:56.235Z");
- add_doc("id", "202", f, "1976-07-05T00:00:00.000Z");
- add_doc("id", "203", f, "1976-07-15T00:07:67.890Z");
- add_doc("id", "204", f, "1976-07-21T00:07:67.890Z");
- add_doc("id", "205", f, "1976-07-13T12:12:25.255Z");
- add_doc("id", "206", f, "1976-07-03T17:01:23.456Z");
- add_doc("id", "207", f, "1976-07-12T12:12:25.255Z");
- add_doc("id", "208", f, "1976-07-15T15:15:15.155Z");
- add_doc("id", "209", f, "1907-07-12T13:13:23.235Z");
- add_doc("id", "2010", f, "1976-07-03T11:02:45.678Z");
- add_doc("id", "2011", f, "1907-07-12T12:12:25.255Z");
- add_doc("id", "2012", f, "2007-07-30T07:07:07.070Z");
- add_doc("id", "2013", f, "1976-07-30T22:22:22.222Z");
- add_doc("id", "2014", f, "1976-07-05T22:22:22.222Z");
+ final String ff = "a_tdt";
+ final String ooo = "00:00:00.000Z";
+ final String xxx = "15:15:15.155Z";
+
+ add_doc(i, "201", f, "1976-07-04T12:08:56.235Z", ff, "1900-01-01T"+ooo);
+ add_doc(i, "202", f, "1976-07-05T00:00:00.000Z", ff, "1976-07-01T"+ooo);
+ add_doc(i, "203", f, "1976-07-15T00:07:67.890Z", ff, "1976-07-04T"+ooo);
+ add_doc(i, "204", f, "1976-07-21T00:07:67.890Z", ff, "1976-07-05T"+ooo);
+ add_doc(i, "205", f, "1976-07-13T12:12:25.255Z", ff, "1976-07-05T"+xxx);
+ add_doc(i, "206", f, "1976-07-03T17:01:23.456Z", ff, "1976-07-07T"+ooo);
+ add_doc(i, "207", f, "1976-07-12T12:12:25.255Z", ff, "1976-07-13T"+ooo);
+ add_doc(i, "208", f, "1976-07-15T15:15:15.155Z", ff, "1976-07-13T"+xxx);
+ add_doc(i, "209", f, "1907-07-12T13:13:23.235Z", ff, "1976-07-15T"+xxx);
+ add_doc(i, "2010", f, "1976-07-03T11:02:45.678Z", ff, "2000-01-01T"+ooo);
+ add_doc(i, "2011", f, "1907-07-12T12:12:25.255Z");
+ add_doc(i, "2012", f, "2007-07-30T07:07:07.070Z");
+ add_doc(i, "2013", f, "1976-07-30T22:22:22.222Z");
+ add_doc(i, "2014", f, "1976-07-05T22:22:22.222Z");
}
@Test
@@ -385,6 +389,42 @@ public class SimpleFacetsTest extends So
,pre+"/int[@name='between'][.='11']"
);
+ assertQ("check before is not inclusive of upper bound by default",
+ req("q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-05T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-07T00:00:00.000Z"
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ )
+ // 2 gaps + pre+post+inner = 5
+ ,"*[count("+pre+"/int)=5]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0' ]"
+
+ ,pre+"/int[@name='before' ][.='5']"
+ );
+ assertQ("check after is not inclusive of lower bound by default",
+ req("q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-03T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-05T00:00:00.000Z"
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ )
+ // 2 gaps + pre+post+inner = 5
+ ,"*[count("+pre+"/int)=5]"
+ ,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='2' ]"
+
+ ,pre+"/int[@name='after' ][.='8']"
+ );
+
+
assertQ("check hardend=false",
req( "q", "*:*"
,"rows", "0"
@@ -431,6 +471,303 @@ public class SimpleFacetsTest extends So
}
+ /** similar to testDateFacets, but a differnet field with test data
+ exactly on on boundary marks */
+ @Test
+ public void testDateFacetsWithIncludeOption() {
+ final String f = "a_tdt";
+ final String pre = "//lst[@name='facet_dates']/lst[@name='"+f+"']";
+
+ assertQ("checking counts for lower",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-16T00:00:00.000Z"
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "lower"
+ )
+ // 15 days + pre+post+inner = 18
+ ,"*[count("+pre+"/int)=18]"
+ ,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']"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-13T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-14T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-15T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='1']"
+ ,pre+"/int[@name='after' ][.='1']"
+ ,pre+"/int[@name='between'][.='8']"
+ );
+
+ assertQ("checking counts for upper",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-16T00:00:00.000Z"
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "upper"
+ )
+ // 15 days + pre+post+inner = 18
+ ,"*[count("+pre+"/int)=18]"
+ ,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' ]"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-13T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-14T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-15T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='2']"
+ ,pre+"/int[@name='after' ][.='1']"
+ ,pre+"/int[@name='between'][.='7']"
+ );
+
+ assertQ("checking counts for lower & upper",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-16T00:00:00.000Z"
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "lower"
+ ,"facet.date.include", "upper"
+ )
+ // 15 days + pre+post+inner = 18
+ ,"*[count("+pre+"/int)=18]"
+ ,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' ]"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-13T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-14T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-15T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='1']"
+ ,pre+"/int[@name='after' ][.='1']"
+ ,pre+"/int[@name='between'][.='8']"
+ );
+
+ assertQ("checking counts for upper & edge",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-16T00:00:00.000Z"
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "upper"
+ ,"facet.date.include", "edge"
+ )
+ // 15 days + pre+post+inner = 18
+ ,"*[count("+pre+"/int)=18]"
+ ,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' ]"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-13T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-14T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-15T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='1']"
+ ,pre+"/int[@name='after' ][.='1']"
+ ,pre+"/int[@name='between'][.='8']"
+ );
+
+ assertQ("checking counts for upper & outer",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-13T00:00:00.000Z" // smaller now
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "upper"
+ ,"facet.date.include", "outer"
+ )
+ // 12 days + pre+post+inner = 15
+ ,"*[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' ]"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='2']"
+ ,pre+"/int[@name='after' ][.='4']"
+ ,pre+"/int[@name='between'][.='5']"
+ );
+
+ assertQ("checking counts for lower & edge",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-13T00:00:00.000Z" // smaller now
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "lower"
+ ,"facet.date.include", "edge"
+ )
+ // 12 days + pre+post+inner = 15
+ ,"*[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']"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='1']"
+ ,pre+"/int[@name='after' ][.='3']"
+ ,pre+"/int[@name='between'][.='6']"
+ );
+
+ assertQ("checking counts for lower & outer",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-13T00:00:00.000Z" // smaller now
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "lower"
+ ,"facet.date.include", "outer"
+ )
+ // 12 days + pre+post+inner = 15
+ ,"*[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']"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='before' ][.='2']"
+ ,pre+"/int[@name='after' ][.='4']"
+ ,pre+"/int[@name='between'][.='5']"
+ );
+
+ assertQ("checking counts for lower & edge & outer",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-13T00:00:00.000Z" // smaller now
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "lower"
+ ,"facet.date.include", "edge"
+ ,"facet.date.include", "outer"
+ )
+ // 12 days + pre+post+inner = 15
+ ,"*[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']"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='2']"
+ ,pre+"/int[@name='after' ][.='4']"
+ ,pre+"/int[@name='between'][.='6']"
+ );
+
+ assertQ("checking counts for all",
+ req( "q", "*:*"
+ ,"rows", "0"
+ ,"facet", "true"
+ ,"facet.date", f
+ ,"facet.date.start", "1976-07-01T00:00:00.000Z"
+ ,"facet.date.end", "1976-07-13T00:00:00.000Z" // smaller now
+ ,"facet.date.gap", "+1DAY"
+ ,"facet.date.other", "all"
+ ,"facet.date.include", "all"
+ )
+ // 12 days + pre+post+inner = 15
+ ,"*[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' ]"
+ ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2' ]"
+ ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-07T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='1976-07-08T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-09T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-10T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-11T00:00:00Z'][.='0']"
+ ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1' ]"
+ ,pre+"/int[@name='before' ][.='2']"
+ ,pre+"/int[@name='after' ][.='4']"
+ ,pre+"/int[@name='between'][.='6']"
+ );
+ }
+
static void indexFacetSingleValued() {
indexFacets("40","t_s1");
}