@Test public void testInfiniteValues() throws Exception { Directory dir = newDirectory(); IndexWriter writer = new IndexWriter( dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT))); Document doc = new Document(); doc.add(new NumericField("double").setDoubleValue(Double.NEGATIVE_INFINITY)); doc.add(new NumericField("long").setLongValue(Long.MIN_VALUE)); writer.addDocument(doc); doc = new Document(); doc.add(new NumericField("double").setDoubleValue(Double.POSITIVE_INFINITY)); doc.add(new NumericField("long").setLongValue(Long.MAX_VALUE)); writer.addDocument(doc); doc = new Document(); doc.add(new NumericField("double").setDoubleValue(0.0)); doc.add(new NumericField("long").setLongValue(0L)); writer.addDocument(doc); writer.close(); IndexSearcher s = new IndexSearcher(dir); Query q = NumericRangeQuery.newLongRange("long", null, null, true, true); TopDocs topDocs = s.search(q, 10); assertEquals("Score doc count", 3, topDocs.scoreDocs.length); q = NumericRangeQuery.newLongRange("long", null, null, false, false); topDocs = s.search(q, 10); assertEquals("Score doc count", 3, topDocs.scoreDocs.length); q = NumericRangeQuery.newLongRange("long", Long.MIN_VALUE, Long.MAX_VALUE, true, true); topDocs = s.search(q, 10); assertEquals("Score doc count", 3, topDocs.scoreDocs.length); q = NumericRangeQuery.newLongRange("long", Long.MIN_VALUE, Long.MAX_VALUE, false, false); topDocs = s.search(q, 10); assertEquals("Score doc count", 1, topDocs.scoreDocs.length); q = NumericRangeQuery.newDoubleRange("double", null, null, true, true); topDocs = s.search(q, 10); assertEquals("Score doc count", 3, topDocs.scoreDocs.length); q = NumericRangeQuery.newDoubleRange("double", null, null, false, false); topDocs = s.search(q, 10); assertEquals("Score doc count", 3, topDocs.scoreDocs.length); s.close(); dir.close(); }
/** we fake a double test using long2double conversion of NumericUtils */ private void testDoubleRange(int precisionStep) throws Exception { final String field = "ascfield" + precisionStep; final long lower = -1000L, upper = +2000L; Query tq = NumericRangeQuery.newDoubleRange( field, precisionStep, NumericUtils.sortableLongToDouble(lower), NumericUtils.sortableLongToDouble(upper), true, true); TopDocs tTopDocs = searcher.search(tq, 1); assertEquals( "Returned count of range query must be equal to inclusive range length", upper - lower + 1, tTopDocs.totalHits); Filter tf = NumericRangeFilter.newDoubleRange( field, precisionStep, NumericUtils.sortableLongToDouble(lower), NumericUtils.sortableLongToDouble(upper), true, true); tTopDocs = searcher.search(new MatchAllDocsQuery(), tf, 1); assertEquals( "Returned count of range filter must be equal to inclusive range length", upper - lower + 1, tTopDocs.totalHits); }
protected <N extends Number> NumericRangeQuery<?> numericRange( Class<N> clazz, String field, @Nullable N min, @Nullable N max, boolean minInc, boolean maxInc) { if (clazz.equals(Integer.class)) { return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc); } else if (clazz.equals(Double.class)) { return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc); } else if (clazz.equals(Float.class)) { return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc); } else if (clazz.equals(Long.class)) { return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc); } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) { return NumericRangeQuery.newIntRange( field, min != null ? min.intValue() : null, max != null ? max.intValue() : null, minInc, maxInc); } else { throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName()); } }
/** * Factory that creates a <code>NumericRangeFilter</code>, that queries a <code>double</code> * range using the default <code>precisionStep</code> {@link NumericUtils#PRECISION_STEP_DEFAULT} * (4). You can have half-open ranges (which are in fact </≤ or >/≥ queries) by * setting the min or max value to <code>null</code>. {@link Double#NaN} will never match a * half-open range, to hit {@code NaN} use a query with {@code min == max == Double.NaN}. By * setting inclusive to false, it will match all documents excluding the bounds, with inclusive * on, the boundaries are hits, too. */ public static NumericRangeFilter<Double> newDoubleRange( final String field, Double min, Double max, final boolean minInclusive, final boolean maxInclusive) { return new NumericRangeFilter<Double>( NumericRangeQuery.newDoubleRange(field, min, max, minInclusive, maxInclusive)); }
@Override public Query getRangeQuery( QParser parser, SchemaField field, String min, String max, boolean minInclusive, boolean maxInclusive) { int ps = precisionStep; Query query = null; switch (type) { case INTEGER: query = NumericRangeQuery.newIntRange( field.getName(), ps, min == null ? null : Integer.parseInt(min), max == null ? null : Integer.parseInt(max), minInclusive, maxInclusive); break; case FLOAT: query = NumericRangeQuery.newFloatRange( field.getName(), ps, min == null ? null : Float.parseFloat(min), max == null ? null : Float.parseFloat(max), minInclusive, maxInclusive); break; case LONG: query = NumericRangeQuery.newLongRange( field.getName(), ps, min == null ? null : Long.parseLong(min), max == null ? null : Long.parseLong(max), minInclusive, maxInclusive); break; case DOUBLE: query = NumericRangeQuery.newDoubleRange( field.getName(), ps, min == null ? null : Double.parseDouble(min), max == null ? null : Double.parseDouble(max), minInclusive, maxInclusive); break; case DATE: query = NumericRangeQuery.newLongRange( field.getName(), ps, min == null ? null : dateField.parseMath(null, min).getTime(), max == null ? null : dateField.parseMath(null, max).getTime(), minInclusive, maxInclusive); break; default: throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field"); } return query; }