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 2011/03/01 02:41:27 UTC

svn commit: r1075613 - in /lucene/dev/branches/branch_3x/solr: ./ 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: Tue Mar  1 01:41:26 2011
New Revision: 1075613

URL: http://svn.apache.org/viewvc?rev=1075613&view=rev
Log:
SOLR-1240: merge 1075603 from trunk, while doing this i discovered that at some point in the past i screwed up the merge of SimpleFacetsTest, so the file contents didn't match the merge props.  this comment is essential a whole copy of that file from trunk as or r1075603

Modified:
    lucene/dev/branches/branch_3x/solr/   (props changed)
    lucene/dev/branches/branch_3x/solr/src/common/org/apache/solr/common/params/FacetParams.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/request/SimpleFacets.java
    lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java

Modified: lucene/dev/branches/branch_3x/solr/src/common/org/apache/solr/common/params/FacetParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/common/org/apache/solr/common/params/FacetParams.java?rev=1075613&r1=1075612&r2=1075613&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/common/org/apache/solr/common/params/FacetParams.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/common/org/apache/solr/common/params/FacetParams.java Tue Mar  1 01:41:26 2011
@@ -159,12 +159,13 @@ public interface FacetParams {
    * exclusive of their end points.
    * </p>
    * <p>
-   * The default value if none are specified is: [lower,upper,edge]
+   * The default value if none are specified is: [lower,upper,edge] <i>(NOTE: This is different then FACET_RANGE_INCLUDE)</i>
    * </p>
    * <p>
    * Can be overriden on a per field basis.
    * </p>
    * @see FacetRangeInclude
+   * @see #FACET_RANGE_INCLUDE
    */
   public static final String FACET_DATE_INCLUDE = FACET_DATE + ".include";
 
@@ -209,13 +210,6 @@ public interface FacetParams {
    * Can be overriden on a per field basis.
    */
   public static final String FACET_RANGE_OTHER = FACET_RANGE + ".other";
-  /**
-   * String indicating whether ranges for numerical range faceting 
-   * should be exclusive or inclusive. By default both the start and
-   * end point are inclusive.
-   * Can be overriden on a per field basis.
-   * @see FacetNumberExclusive
-   */
 
   /**
    * <p>
@@ -224,7 +218,7 @@ public interface FacetParams {
    * exclusive of their end points.
    * </p>
    * <p>
-   * The default value if none are specified is: [lower,upper,edge]
+   * The default value if none are specified is: lower
    * </p>
    * <p>
    * Can be overriden on a per field basis.
@@ -314,15 +308,16 @@ public interface FacetParams {
     }
     /**
      * Convinience method for parsing the param value according to the 
-     * correct semantics.
+     * correct semantics and applying the default of "LOWER"
      */
     public static EnumSet<FacetRangeInclude> parseParam(final String[] param) {
       // short circut for default behavior
       if (null == param || 0 == param.length ) 
-        return EnumSet.of(LOWER, UPPER, EDGE);
+        return EnumSet.of(LOWER);
 
       // build up set containing whatever is specified
-      final EnumSet<FacetRangeInclude> include = EnumSet.noneOf(FacetRangeInclude.class);
+      final EnumSet<FacetRangeInclude> include 
+        = EnumSet.noneOf(FacetRangeInclude.class);
       for (final String o : param) {
         include.add(FacetRangeInclude.get(o));
       }

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/request/SimpleFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/request/SimpleFacets.java?rev=1075613&r1=1075612&r2=1075613&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/request/SimpleFacets.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/request/SimpleFacets.java Tue Mar  1 01:41:26 2011
@@ -658,8 +658,16 @@ public class SimpleFacets {
 
     final int minCount = params.getFieldInt(f,FacetParams.FACET_MINCOUNT, 0);
 
-    final EnumSet<FacetRangeInclude> include = FacetRangeInclude.parseParam
-        (params.getFieldParams(f,FacetParams.FACET_DATE_INCLUDE));
+    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<FacetRangeInclude> include = 
+      (null == iStrs || 0 == iStrs.length ) ?
+      EnumSet.of(FacetRangeInclude.LOWER, 
+                 FacetRangeInclude.UPPER, 
+                 FacetRangeInclude.EDGE)
+      : FacetRangeInclude.parseParam(iStrs);
 
     try {
       Date low = start;

Modified: lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java?rev=1075613&r1=1075612&r2=1075613&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/request/SimpleFacetsTest.java Tue Mar  1 01:41:26 2011
@@ -69,18 +69,30 @@ public class SimpleFacetsTest extends So
   }
 
   static void indexSimpleFacetCounts() {
-    add_doc("id", "42", "trait_s", "Tool", "trait_s", "Obnoxious",
-                 "name", "Zapp Brannigan");
+    add_doc("id", "42", 
+            "range_facet_f", "35.3", 
+            "trait_s", "Tool", "trait_s", "Obnoxious",
+            "name", "Zapp Brannigan");
     add_doc("id", "43" ,
-                 "title", "Democratic Order of Planets");
-    add_doc("id", "44", "trait_s", "Tool",
-                 "name", "The Zapper");
-    add_doc("id", "45", "trait_s", "Chauvinist",
-                 "title", "25 star General");
-    add_doc("id", "46", "trait_s", "Obnoxious",
-                 "subject", "Defeated the pacifists of the Gandhi nebula");
-    add_doc("id", "47", "trait_s", "Pig",
-                 "text", "line up and fly directly at the enemy death cannons, clogging them with wreckage!");   
+            "range_facet_f", "28.789", 
+            "title", "Democratic Order of Planets");
+    add_doc("id", "44", 
+            "range_facet_f", "15.97", 
+            "trait_s", "Tool",
+            "name", "The Zapper");
+    add_doc("id", "45", 
+            "range_facet_f", "30.0", 
+            "trait_s", "Chauvinist",
+            "title", "25 star General");
+    add_doc("id", "46", 
+            "range_facet_f", "20.0", 
+            "trait_s", "Obnoxious",
+            "subject", "Defeated the pacifists of the Gandhi nebula");
+    add_doc("id", "47", 
+            "range_facet_f", "28.62", 
+            "trait_s", "Pig",
+            "text", "line up and fly directly at the enemy death cannons, clogging them with wreckage!",
+            "zerolen_s","");   
   }
 
   @Test
@@ -296,51 +308,89 @@ public class SimpleFacetsTest extends So
             ,"//int[2][@name='Obnoxious'][.='1']"
             ,"//int[3][@name='Tool'][.='2']"
             );
+
+
+     assertQ(req("q", "id:[42 TO 47]"
+                ,"facet", "true"
+                ,"facet.method","fc"
+                ,"fq", "id:[42 TO 45]"
+                ,"facet.field", "zerolen_s"
+                )
+            ,"*[count(//lst[@name='zerolen_s']/int)=1]"
+     );
   }
 
   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
+  public void testTrieDateFacets() {
+    helpTestDateFacets("bday", false);
+  }
+  @Test
   public void testDateFacets() {
-    final String f = "bday";
-    final String pre = "//lst[@name='facet_dates']/lst[@name='"+f+"']";
+    helpTestDateFacets("bday_pdt", false);
+  }
+
+  @Test
+  public void testTrieDateRangeFacets() {
+    helpTestDateFacets("bday", true);
+  }
+  @Test
+  public void testDateRangeFacets() {
+    helpTestDateFacets("bday_pdt", true);
+  }
+
+  private void helpTestDateFacets(final String fieldName, 
+                                  final boolean rangeMode) {
+    final String p = rangeMode ? "facet.range" : "facet.date";
+    final String b = rangeMode ? "facet_ranges" : "facet_dates";
+    final String f = fieldName;
+    final String c = (rangeMode ? "/lst[@name='counts']" : "");
+    final String pre = "//lst[@name='"+b+"']/lst[@name='"+f+"']" + c;
+    final String meta = pre + (rangeMode ? "/../" : "");
+
+    
+    // date faceting defaults to include both endpoints, 
+    // range faceting defaults to including only lower
+    // doc exists with value @ 00:00:00.000 on July5
+    final String jul4 = rangeMode ? "[.='1'  ]" : "[.='2'  ]";
 
     assertQ("check counts for month of facet by day",
             req( "q", "*:*"
                 ,"rows", "0"
                 ,"facet", "true"
-                ,"facet.date", f
-                ,"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"
-                )
-            // 31 days + pre+post+inner = 34
-            ,"*[count("+pre+"/int)=34]"
-            ,pre+"/int[@name='1976-07-01T00:00:00Z'][.='0'  ]"
-            ,pre+"/int[@name='1976-07-02T00:00:00Z'][.='0'  ]"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-01T00:00:00.000Z+1MONTH"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                )
+            ,"*[count("+pre+"/int)="+(rangeMode ? 31 : 34)+"]"
+            ,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'  ]"
-            // july4th = 2 because exists doc @ 00:00:00.000 on July5
-            // (date faceting is inclusive)
-            ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='2'  ]"
+            ,pre+"/int[@name='1976-07-04T00:00:00Z']" + jul4
             ,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'][.='0']"
@@ -368,9 +418,9 @@ public class SimpleFacetsTest extends So
             ,pre+"/int[@name='1976-07-30T00:00:00Z'][.='1'  ]"
             ,pre+"/int[@name='1976-07-31T00:00:00Z'][.='0']"
             
-            ,pre+"/int[@name='before' ][.='2']"
-            ,pre+"/int[@name='after'  ][.='1']"
-            ,pre+"/int[@name='between'][.='11']"
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='11']"
             
             );
 
@@ -378,96 +428,739 @@ public class SimpleFacetsTest extends So
             req( "q", "*:*"
                 ,"rows", "0"
                 ,"facet", "true"
-                ,"facet.date", f
-                ,"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"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-01T00:00:00.000Z+1MONTH"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
                 ,"facet.mincount", "1"
                 )
-            // 31 days + pre+post+inner = 34
-            ,"*[count("+pre+"/int)=11]"
+            ,"*[count("+pre+"/int)="+(rangeMode ? 8 : 11)+"]"
             ,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2'  ]"
-            // july4th = 2 because exists doc @ 00:00:00.000 on July5
-            // (date faceting is inclusive)
-            ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='2'  ]"
+            ,pre+"/int[@name='1976-07-04T00:00:00Z']" + jul4
             ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2'  ]"
             ,pre+"/int[@name='1976-07-12T00:00:00Z'][.='1'  ]"
             ,pre+"/int[@name='1976-07-13T00:00:00Z'][.='1'  ]"
             ,pre+"/int[@name='1976-07-15T00:00:00Z'][.='2'  ]"
             ,pre+"/int[@name='1976-07-21T00:00:00Z'][.='1'  ]"
             ,pre+"/int[@name='1976-07-30T00:00:00Z'][.='1'  ]"
-            ,pre+"/int[@name='before' ][.='2']"
-            ,pre+"/int[@name='after'  ][.='1']"
-            ,pre+"/int[@name='between'][.='11']"
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='11']"
             );
 
     assertQ("check counts for month of facet by day with field mincount = 1",
             req( "q", "*:*"
                 ,"rows", "0"
                 ,"facet", "true"
-                ,"facet.date", f
-                ,"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"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-01T00:00:00.000Z+1MONTH"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
                 ,"f." + f + ".facet.mincount", "2"
                 )
-            // 31 days + pre+post+inner = 34
-            ,"*[count("+pre+"/int)=7]"
+            ,"*[count("+pre+"/int)="+(rangeMode ? 3 : 7)+"]"
             ,pre+"/int[@name='1976-07-03T00:00:00Z'][.='2'  ]"
-            // july4th = 2 because exists doc @ 00:00:00.000 on July5
-            // (date faceting is inclusive)
-            ,pre+"/int[@name='1976-07-04T00:00:00Z'][.='2'  ]"
+            ,pre+(rangeMode ? "" : "/int[@name='1976-07-04T00:00:00Z']" +jul4)
             ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2'  ]"
             ,pre+"/int[@name='1976-07-15T00:00:00Z'][.='2'  ]"
-            ,pre+"/int[@name='before' ][.='2']"
-            ,pre+"/int[@name='after'  ][.='1']"
-            ,pre+"/int[@name='between'][.='11']"
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='11']"
             );
 
+    assertQ("check before is not inclusive of upper bound by default",
+            req("q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start",  "1976-07-05T00:00:00.000Z"
+                ,p+".end",    "1976-07-07T00:00:00.000Z"
+                ,p+".gap",    "+1DAY"
+                ,p+".other",  "all"
+                )
+            ,"*[count("+pre+"/int)="+(rangeMode ? 2 : 5)+"]"
+            ,pre+"/int[@name='1976-07-05T00:00:00Z'][.='2'  ]"
+            ,pre+"/int[@name='1976-07-06T00:00:00Z'][.='0']"
+            
+            ,meta+"/int[@name='before' ][.='5']"
+            );
+    assertQ("check after is not inclusive of lower bound by default (for dates)",
+            req("q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start",  "1976-07-03T00:00:00.000Z"
+                ,p+".end",    "1976-07-05T00:00:00.000Z"
+                ,p+".gap",    "+1DAY"
+                ,p+".other",  "all"
+                )
+            ,"*[count("+pre+"/int)="+(rangeMode ? 2 : 5)+"]"
+            ,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)+"']"
+            );
+            
+
     assertQ("check hardend=false",
             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"
-                ,"facet.date.gap",    "+5DAYS"
-                ,"facet.date.other",  "all"
-                ,"facet.date.hardend","false"
+                ,p, f
+                ,p+".start",  "1976-07-01T00:00:00.000Z"
+                ,p+".end",    "1976-07-13T00:00:00.000Z"
+                ,p+".gap",    "+5DAYS"
+                ,p+".other",  "all"
+                ,p+".hardend","false"
                 )
-            // 3 gaps + pre+post+inner = 6
-            ,"*[count("+pre+"/int)=6]"
+            ,"*[count("+pre+"/int)="+(rangeMode ? 3 : 6)+"]"
             ,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'  ]"
             
-            ,pre+"/int[@name='before' ][.='2']"
-            ,pre+"/int[@name='after'  ][.='3']"
-            ,pre+"/int[@name='between'][.='9']"
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='3']"
+            ,meta+"/int[@name='between'][.='9']"
             );
 
     assertQ("check hardend=true",
             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"
-                ,"facet.date.gap",    "+5DAYS"
-                ,"facet.date.other",  "all"
-                ,"facet.date.hardend","true"
+                ,p, f
+                ,p+".start",  "1976-07-01T00:00:00.000Z"
+                ,p+".end",    "1976-07-13T00:00:00.000Z"
+                ,p+".gap",    "+5DAYS"
+                ,p+".other",  "all"
+                ,p+".hardend","true"
                 )
-            // 3 gaps + pre+post+inner = 6
-            ,"*[count("+pre+"/int)=6]"
+            ,"*[count("+pre+"/int)="+(rangeMode ? 3 : 6)+"]"
             ,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'  ]"
             
-            ,pre+"/int[@name='before' ][.='2']"
-            ,pre+"/int[@name='after'  ][.='6']"
-            ,pre+"/int[@name='between'][.='6']"
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='6']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+    
+  }
+
+  @Test
+  public void testTrieDateFacetsWithIncludeOption() {
+    helpTestDateFacetsWithIncludeOption("a_tdt", false);
+  }
+  @Test
+  public void testDateFacetsWithIncludeOption() {
+    helpTestDateFacetsWithIncludeOption("a_pdt", false);
+  }
+
+  @Test
+  public void testTrieDateRangeFacetsWithIncludeOption() {
+    helpTestDateFacetsWithIncludeOption("a_tdt", true);
+  }
+  @Test
+  public void testDateRangeFacetsWithIncludeOption() {
+    helpTestDateFacetsWithIncludeOption("a_pdt", true);
+  }
+
+  /** similar to helpTestDateFacets, but for differnet fields with test data 
+      exactly on 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";
+    final String f = fieldName;
+    final String c = (rangeMode ? "/lst[@name='counts']" : "");
+    final String pre = "//lst[@name='"+b+"']/lst[@name='"+f+"']" + c;
+    final String meta = pre + (rangeMode ? "/../" : "");
+
+    assertQ("checking counts for lower",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-16T00:00:00.000Z"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "lower"
+                )
+            // 15 days + pre+post+inner = 18
+            ,"*[count("+pre+"/int)="+(rangeMode ? 15 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='1']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='8']"
+            );
+
+    assertQ("checking counts for upper",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-16T00:00:00.000Z"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "upper"
+                )
+            // 15 days + pre+post+inner = 18
+            ,"*[count("+pre+"/int)="+(rangeMode ? 15 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='7']"
+            );
+
+    assertQ("checking counts for lower & upper",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-16T00:00:00.000Z"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "lower"
+                ,p+".include", "upper"
+                )
+            // 15 days + pre+post+inner = 18
+            ,"*[count("+pre+"/int)="+(rangeMode ? 15 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='1']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='8']"
+            );
+
+    assertQ("checking counts for upper & edge",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-16T00:00:00.000Z"
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "upper"
+                ,p+".include", "edge"
+                )
+            // 15 days + pre+post+inner = 18
+            ,"*[count("+pre+"/int)="+(rangeMode ? 15 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='1']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='8']"
+            );
+
+    assertQ("checking counts for upper & outer",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-13T00:00:00.000Z" // smaller now
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "upper"
+                ,p+".include", "outer"
+                )
+            // 12 days + pre+post+inner = 15
+            ,"*[count("+pre+"/int)="+(rangeMode ? 12 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='4']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ("checking counts for lower & edge",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-13T00:00:00.000Z" // smaller now
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "lower"
+                ,p+".include", "edge"
+                )
+            // 12 days + pre+post+inner = 15
+            ,"*[count("+pre+"/int)="+(rangeMode ? 12 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='1']"
+            ,meta+"/int[@name='after'  ][.='3']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+
+    assertQ("checking counts for lower & outer",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-13T00:00:00.000Z" // smaller now
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "lower"
+                ,p+".include", "outer"
+                )
+            // 12 days + pre+post+inner = 15
+            ,"*[count("+pre+"/int)="+(rangeMode ? 12 : 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']"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='4']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ("checking counts for lower & edge & outer",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-13T00:00:00.000Z" // smaller now
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "lower"
+                ,p+".include", "edge"
+                ,p+".include", "outer"
+                )
+            // 12 days + pre+post+inner = 15
+            ,"*[count("+pre+"/int)="+(rangeMode ? 12 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='4']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+
+    assertQ("checking counts for all",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,p, f
+                ,p+".start", "1976-07-01T00:00:00.000Z"
+                ,p+".end",   "1976-07-13T00:00:00.000Z" // smaller now
+                ,p+".gap",   "+1DAY"
+                ,p+".other", "all"
+                ,p+".include", "all"
+                )
+            // 12 days + pre+post+inner = 15
+            ,"*[count("+pre+"/int)="+(rangeMode ? 12 : 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'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='4']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+  }
+
+  @Test
+  public void testNumericRangeFacetsTrieFloat() {
+    helpTestFractionalNumberRangeFacets("range_facet_f");
+  }
+  @Test
+  public void testNumericRangeFacetsTrieDouble() {
+    helpTestFractionalNumberRangeFacets("range_facet_d");
+  }
+  @Test
+  public void testNumericRangeFacetsSortableFloat() {
+    helpTestFractionalNumberRangeFacets("range_facet_sf");
+  }
+  @Test
+  public void testNumericRangeFacetsSortableDouble() {
+    helpTestFractionalNumberRangeFacets("range_facet_sd");
+  }
+  private void helpTestFractionalNumberRangeFacets(final String fieldName) {
+
+    final String f = fieldName;
+    final String pre = "//lst[@name='facet_ranges']/lst[@name='"+f+"']/lst[@name='counts']";
+    final String meta = pre + "/../";
+
+    assertQ(f+": checking counts for lower",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "10"
+                ,"facet.range.end",   "50"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "lower"
+                )
+            ,"*[count("+pre+"/int)=4]"
+            ,pre+"/int[@name='10.0'][.='1'  ]"
+            ,pre+"/int[@name='20.0'][.='3'  ]"
+            ,pre+"/int[@name='30.0'][.='2'  ]"
+            ,pre+"/int[@name='40.0'][.='0'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+
+    assertQ(f + ":checking counts for upper",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "10"
+                ,"facet.range.end",   "50"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "upper"
+                )
+            ,"*[count("+pre+"/int)=4]"
+            ,pre+"/int[@name='10.0'][.='2'  ]"
+            ,pre+"/int[@name='20.0'][.='3'  ]"
+            ,pre+"/int[@name='30.0'][.='1'  ]"
+            ,pre+"/int[@name='40.0'][.='0'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+
+    assertQ(f + ":checking counts for lower & upper",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "10"
+                ,"facet.range.end",   "50"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "upper"
+                ,"facet.range.include", "lower"
+                )
+            ,"*[count("+pre+"/int)=4]"
+            ,pre+"/int[@name='10.0'][.='2'  ]"
+            ,pre+"/int[@name='20.0'][.='4'  ]"
+            ,pre+"/int[@name='30.0'][.='2'  ]"
+            ,pre+"/int[@name='40.0'][.='0'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+
+    assertQ(f + ": checking counts for upper & edge",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "20"
+                ,"facet.range.end",   "50"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "upper"
+                ,"facet.range.include", "edge"
+                )
+            ,"*[count("+pre+"/int)=3]"
+            ,pre+"/int[@name='20.0'][.='4'  ]"
+            ,pre+"/int[@name='30.0'][.='1'  ]"
+            ,pre+"/int[@name='40.0'][.='0'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='1']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ(f + ": checking counts for upper & outer",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "10"
+                ,"facet.range.end",   "30"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "upper"
+                ,"facet.range.include", "outer"
+                )
+            ,"*[count("+pre+"/int)=2]"
+            ,pre+"/int[@name='10.0'][.='2'  ]"
+            ,pre+"/int[@name='20.0'][.='3'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='2']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ(f + ": checking counts for lower & edge",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "10"
+                ,"facet.range.end",   "30"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "lower"
+                ,"facet.range.include", "edge"
+                )
+            ,"*[count("+pre+"/int)=2]"
+            ,pre+"/int[@name='10.0'][.='1'  ]"
+            ,pre+"/int[@name='20.0'][.='4'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ(f + ": checking counts for lower & outer",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "20"
+                ,"facet.range.end",   "40"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "lower"
+                ,"facet.range.include", "outer"
+                )
+            ,"*[count("+pre+"/int)=2]"
+            ,pre+"/int[@name='20.0'][.='3'  ]"
+            ,pre+"/int[@name='30.0'][.='2'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ(f + ": checking counts for lower & edge & outer",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "20"
+                ,"facet.range.end",   "35.3"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.hardend", "true"
+                ,"facet.range.include", "lower"
+                ,"facet.range.include", "edge"
+                ,"facet.range.include", "outer"
+                )
+            ,"*[count("+pre+"/int)=2]"
+            ,pre+"/int[@name='20.0'][.='3'  ]"
+            ,pre+"/int[@name='30.0'][.='2'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+
+    assertQ(f + ": checking counts for include all",
+            req( "q", "*:*"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "20"
+                ,"facet.range.end",   "35.3"
+                ,"facet.range.gap",   "10"
+                ,"facet.range.other", "all"
+                ,"facet.range.hardend", "true"
+                ,"facet.range.include", "all"
+                )
+            ,"*[count("+pre+"/int)=2]"
+            ,pre+"/int[@name='20.0'][.='4'  ]"
+            ,pre+"/int[@name='30.0'][.='2'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='2']"
+            ,meta+"/int[@name='after'  ][.='1']"
+            ,meta+"/int[@name='between'][.='5']"
+            );
+  }
+
+  @Test
+  public void testNumericRangeFacetsTrieInt() {
+    helpTestWholeNumberRangeFacets("id");
+  }
+  @Test
+  public void testNumericRangeFacetsTrieLong() {
+    helpTestWholeNumberRangeFacets("range_facet_l");
+  }
+  @Test
+  public void testNumericRangeFacetsSortableInt() {
+    helpTestWholeNumberRangeFacets("range_facet_si");
+  }
+  @Test
+  public void testNumericRangeFacetsSortableLong() {
+    helpTestWholeNumberRangeFacets("range_facet_sl");
+  }
+
+  private void helpTestWholeNumberRangeFacets(final String fieldName) {
+
+    // the float test covers a lot of the weird edge cases
+    // here we just need some basic sanity checking of the parsing
+
+    final String f = fieldName;
+    final String pre = "//lst[@name='facet_ranges']/lst[@name='"+f+"']/lst[@name='counts']";
+    final String meta = pre + "/../";
+
+    assertQ(f+": checking counts for lower",
+            req( "q", "id:[30 TO 60]"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "35"
+                ,"facet.range.end",   "50"
+                ,"facet.range.gap",   "5"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "lower"
+                )
+            ,"*[count("+pre+"/int)=3]"
+            ,pre+"/int[@name='35'][.='0'  ]"
+            ,pre+"/int[@name='40'][.='3'  ]"
+            ,pre+"/int[@name='45'][.='3'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='6']"
+            );
+
+    assertQ(f + ":checking counts for upper",
+            req( "q", "id:[30 TO 60]"
+                ,"rows", "0"
+                ,"facet", "true"
+                ,"facet.range", f
+                ,"facet.range.start", "35"
+                ,"facet.range.end",   "50"
+                ,"facet.range.gap",   "5"
+                ,"facet.range.other", "all"
+                ,"facet.range.include", "upper"
+                )
+            ,"*[count("+pre+"/int)=3]"
+            ,pre+"/int[@name='35'][.='0'  ]"
+            ,pre+"/int[@name='40'][.='4'  ]"
+            ,pre+"/int[@name='45'][.='2'  ]"
+            //
+            ,meta+"/int[@name='before' ][.='0']"
+            ,meta+"/int[@name='after'  ][.='0']"
+            ,meta+"/int[@name='between'][.='6']"
             );
     
   }