@Override public Filter getFilter(Element e) throws ParserException { String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName"); String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm"); String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm"); boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true); boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true); int precisionStep = DOMUtils.getAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT); String type = DOMUtils.getAttribute(e, "type", "int"); try { Filter filter; if (type.equalsIgnoreCase("int")) { filter = NumericRangeFilter.newIntRange(field, precisionStep, Integer .valueOf(lowerTerm), Integer.valueOf(upperTerm), lowerInclusive, upperInclusive); } else if (type.equalsIgnoreCase("long")) { filter = NumericRangeFilter.newLongRange(field, precisionStep, Long .valueOf(lowerTerm), Long.valueOf(upperTerm), lowerInclusive, upperInclusive); } else if (type.equalsIgnoreCase("double")) { filter = NumericRangeFilter.newDoubleRange(field, precisionStep, Double .valueOf(lowerTerm), Double.valueOf(upperTerm), lowerInclusive, upperInclusive); } else if (type.equalsIgnoreCase("float")) { filter = NumericRangeFilter.newFloatRange(field, precisionStep, Float .valueOf(lowerTerm), Float.valueOf(upperTerm), lowerInclusive, upperInclusive); } else { throw new ParserException("type attribute must be one of: [long, int, double, float]"); } return filter; } catch (NumberFormatException nfe) { if (strictMode) { throw new ParserException("Could not parse lowerTerm or upperTerm into a number", nfe); } return NO_MATCH_FILTER; } }
@SuppressWarnings({"unchecked","rawtypes"}) public void testGetFilterInt() throws Exception { NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder(); filterBuilder.setStrictMode(true); String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>"; Document doc = getDocumentFromString(xml); Filter filter = filterBuilder.getFilter(doc.getDocumentElement()); assertTrue(filter instanceof NumericRangeFilter<?>); NumericRangeFilter<Integer> numRangeFilter = (NumericRangeFilter<Integer>) filter; assertEquals(Integer.valueOf(-1), numRangeFilter.getMin()); assertEquals(Integer.valueOf(10), numRangeFilter.getMax()); assertEquals("AGE", numRangeFilter.getField()); assertTrue(numRangeFilter.includesMin()); assertTrue(numRangeFilter.includesMax()); String xml2 = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>"; Document doc2 = getDocumentFromString(xml2); Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement()); assertTrue(filter2 instanceof NumericRangeFilter); NumericRangeFilter<Integer> numRangeFilter2 = (NumericRangeFilter) filter2; assertEquals(Integer.valueOf(-1), numRangeFilter2.getMin()); assertEquals(Integer.valueOf(10), numRangeFilter2.getMax()); assertEquals("AGE", numRangeFilter2.getField()); assertTrue(numRangeFilter2.includesMin()); assertFalse(numRangeFilter2.includesMax()); }
@SuppressWarnings({"unchecked","rawtypes"}) public void testGetFilterLong() throws Exception { NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder(); filterBuilder.setStrictMode(true); String xml = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>"; Document doc = getDocumentFromString(xml); Filter filter = filterBuilder.getFilter(doc.getDocumentElement()); assertTrue(filter instanceof NumericRangeFilter<?>); NumericRangeFilter<Long> numRangeFilter = (NumericRangeFilter) filter; assertEquals(Long.valueOf(-2321L), numRangeFilter.getMin()); assertEquals(Long.valueOf(60000000L), numRangeFilter.getMax()); assertEquals("AGE", numRangeFilter.getField()); assertTrue(numRangeFilter.includesMin()); assertTrue(numRangeFilter.includesMax()); String xml2 = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>"; Document doc2 = getDocumentFromString(xml2); Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement()); assertTrue(filter2 instanceof NumericRangeFilter<?>); NumericRangeFilter<Long> numRangeFilter2 = (NumericRangeFilter) filter2; assertEquals(Long.valueOf(-2321L), numRangeFilter2.getMin()); assertEquals(Long.valueOf(60000000L), numRangeFilter2.getMax()); assertEquals("AGE", numRangeFilter2.getField()); assertTrue(numRangeFilter2.includesMin()); assertFalse(numRangeFilter2.includesMax()); }
@SuppressWarnings({"unchecked","rawtypes"}) public void testGetFilterDouble() throws Exception { NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder(); filterBuilder.setStrictMode(true); String xml = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>"; Document doc = getDocumentFromString(xml); Filter filter = filterBuilder.getFilter(doc.getDocumentElement()); assertTrue(filter instanceof NumericRangeFilter<?>); NumericRangeFilter<Double> numRangeFilter = (NumericRangeFilter) filter; assertEquals(Double.valueOf(-23.21d), numRangeFilter.getMin()); assertEquals(Double.valueOf(60000.00023d), numRangeFilter.getMax()); assertEquals("AGE", numRangeFilter.getField()); assertTrue(numRangeFilter.includesMin()); assertTrue(numRangeFilter.includesMax()); String xml2 = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>"; Document doc2 = getDocumentFromString(xml2); Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement()); assertTrue(filter2 instanceof NumericRangeFilter<?>); NumericRangeFilter<Double> numRangeFilter2 = (NumericRangeFilter) filter2; assertEquals(Double.valueOf(-23.21d), numRangeFilter2.getMin()); assertEquals(Double.valueOf(60000.00023d), numRangeFilter2.getMax()); assertEquals("AGE", numRangeFilter2.getField()); assertTrue(numRangeFilter2.includesMin()); assertFalse(numRangeFilter2.includesMax()); }
@SuppressWarnings({"unchecked","rawtypes"}) public void testGetFilterFloat() throws Exception { NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder(); filterBuilder.setStrictMode(true); String xml = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>"; Document doc = getDocumentFromString(xml); Filter filter = filterBuilder.getFilter(doc.getDocumentElement()); assertTrue(filter instanceof NumericRangeFilter<?>); NumericRangeFilter<Float> numRangeFilter = (NumericRangeFilter) filter; assertEquals(Float.valueOf(-2.321432f), numRangeFilter.getMin()); assertEquals(Float.valueOf(32432.23f), numRangeFilter.getMax()); assertEquals("AGE", numRangeFilter.getField()); assertTrue(numRangeFilter.includesMin()); assertTrue(numRangeFilter.includesMax()); String xml2 = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />"; Document doc2 = getDocumentFromString(xml2); Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement()); assertTrue(filter2 instanceof NumericRangeFilter<?>); NumericRangeFilter<Float> numRangeFilter2 = (NumericRangeFilter) filter2; assertEquals(Float.valueOf(-2.321432f), numRangeFilter2.getMin()); assertEquals(Float.valueOf(32432.23f), numRangeFilter2.getMax()); assertEquals("AGE", numRangeFilter2.getField()); assertTrue(numRangeFilter2.includesMin()); assertFalse(numRangeFilter2.includesMax()); }
@Override public Filter getFilter(Element element) throws ParserException { String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(element, "fieldName"); String timeUnit = DOMUtils.getAttribute(element, "timeUnit", "days"); Integer calUnit = timeUnits.get(timeUnit); if (calUnit == null) { throw new ParserException("Illegal time unit:" + timeUnit + " - must be days, months or years"); } int agoStart = DOMUtils.getAttribute(element, "from", 0); int agoEnd = DOMUtils.getAttribute(element, "to", 0); if (agoStart < agoEnd) { int oldAgoStart = agoStart; agoStart = agoEnd; agoEnd = oldAgoStart; } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Calendar start = Calendar.getInstance(); start.add(calUnit, agoStart * -1); Calendar end = Calendar.getInstance(); end.add(calUnit, agoEnd * -1); return NumericRangeFilter.newIntRange(fieldName, Integer.valueOf(sdf.format(start.getTime())), Integer.valueOf(sdf.format(end.getTime())), true, true); }
public void testNumericDateFilter() throws Exception { // pub date of Lucene in Action, Second Edition and // JUnit in ACtion, Second Edition is May 2010 Filter filter = NumericRangeFilter.newIntRange("pubmonth", 201001, 201006, true, true); assertEquals(2, TestUtil.hitCount(searcher, allBooks, filter)); }
public Filter toFilter () { return NumericRangeFilter.newIntRange(this.field, this.start, this.end, true, true); }
/** Given a latitude and longitude (in degrees) and the * maximum great circle (surface of the earth) distance, * returns a simple Filter bounding box to "fast match" * candidates. */ public static Filter getBoundingBoxFilter(double originLat, double originLng, double maxDistanceKM) { // Basic bounding box geo math from // http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates, // licensed under creative commons 3.0: // http://creativecommons.org/licenses/by/3.0 // TODO: maybe switch to recursive prefix tree instead // (in lucene/spatial)? It should be more efficient // since it's a 2D trie... // Degrees -> Radians: double originLatRadians = Math.toRadians(originLat); double originLngRadians = Math.toRadians(originLng); double angle = maxDistanceKM / (SloppyMath.earthDiameter(originLat) / 2.0); double minLat = originLatRadians - angle; double maxLat = originLatRadians + angle; double minLng; double maxLng; if (minLat > Math.toRadians(-90) && maxLat < Math.toRadians(90)) { double delta = Math.asin(Math.sin(angle)/Math.cos(originLatRadians)); minLng = originLngRadians - delta; if (minLng < Math.toRadians(-180)) { minLng += 2 * Math.PI; } maxLng = originLngRadians + delta; if (maxLng > Math.toRadians(180)) { maxLng -= 2 * Math.PI; } } else { // The query includes a pole! minLat = Math.max(minLat, Math.toRadians(-90)); maxLat = Math.min(maxLat, Math.toRadians(90)); minLng = Math.toRadians(-180); maxLng = Math.toRadians(180); } BooleanFilter f = new BooleanFilter(); // Add latitude range filter: f.add(NumericRangeFilter.newDoubleRange("latitude", Math.toDegrees(minLat), Math.toDegrees(maxLat), true, true), BooleanClause.Occur.MUST); // Add longitude range filter: if (minLng > maxLng) { // The bounding box crosses the international date // line: BooleanFilter lonF = new BooleanFilter(); lonF.add(NumericRangeFilter.newDoubleRange("longitude", Math.toDegrees(minLng), null, true, true), BooleanClause.Occur.SHOULD); lonF.add(NumericRangeFilter.newDoubleRange("longitude", null, Math.toDegrees(maxLng), true, true), BooleanClause.Occur.SHOULD); f.add(lonF, BooleanClause.Occur.MUST); } else { f.add(NumericRangeFilter.newDoubleRange("longitude", Math.toDegrees(minLng), Math.toDegrees(maxLng), true, true), BooleanClause.Occur.MUST); } return f; }