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>int</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>. By setting inclusive to false, it will match all * documents excluding the bounds, with inclusive on, the boundaries are hits, too. */ public static NumericRangeFilter<Integer> newIntRange( final String field, Integer min, Integer max, final boolean minInclusive, final boolean maxInclusive) { return new NumericRangeFilter<Integer>( NumericRangeQuery.newIntRange(field, min, max, minInclusive, maxInclusive)); }
/** * Tests NumericRangeQuery on a multi-valued field (multiple numeric values per document). This * test ensures, that a classical TermRangeQuery returns exactly the same document numbers as * NumericRangeQuery (see SOLR-1322 for discussion) and the multiple precision terms per numeric * value do not interfere with multiple numeric values. */ public void testMultiValuedNRQ() throws Exception { Directory directory = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter( random(), directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())) .setMaxBufferedDocs(_TestUtil.nextInt(random(), 50, 1000))); DecimalFormat format = new DecimalFormat("00000000000", new DecimalFormatSymbols(Locale.US)); int num = atLeast(500); for (int l = 0; l < num; l++) { Document doc = new Document(); for (int m = 0, c = random().nextInt(10); m <= c; m++) { int value = random().nextInt(Integer.MAX_VALUE); doc.add(newStringField("asc", format.format(value), Field.Store.NO)); doc.add(new IntField("trie", value, Field.Store.NO)); } writer.addDocument(doc); } IndexReader reader = writer.getReader(); writer.close(); IndexSearcher searcher = newSearcher(reader); num = atLeast(50); for (int i = 0; i < num; i++) { int lower = random().nextInt(Integer.MAX_VALUE); int upper = random().nextInt(Integer.MAX_VALUE); if (lower > upper) { int a = lower; lower = upper; upper = a; } TermRangeQuery cq = TermRangeQuery.newStringRange( "asc", format.format(lower), format.format(upper), true, true); NumericRangeQuery<Integer> tq = NumericRangeQuery.newIntRange("trie", lower, upper, true, true); TopDocs trTopDocs = searcher.search(cq, 1); TopDocs nrTopDocs = searcher.search(tq, 1); assertEquals( "Returned count for NumericRangeQuery and TermRangeQuery must be equal", trTopDocs.totalHits, nrTopDocs.totalHits); } reader.close(); directory.close(); }
@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; }