@Override public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) { String f = field.getName(); BytesRef low = part1 == null ? null : getCollationKey(f, part1); BytesRef high = part2 == null ? null : getCollationKey(f, part2); if (!field.indexed() && field.hasDocValues()) { if (field.multiValued()) { return new ConstantScoreQuery(DocTermOrdsRangeFilter.newBytesRefRange( field.getName(), low, high, minInclusive, maxInclusive)); } else { return new ConstantScoreQuery(FieldCacheRangeFilter.newBytesRefRange( field.getName(), low, high, minInclusive, maxInclusive)); } } else { return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive); } }
public void testRanges() throws Exception { Directory dir = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), dir); Document doc = new Document(); Field field = newField("field", "", StringField.TYPE_STORED); Collator collator = Collator.getInstance(); // uses -Dtests.locale if (random().nextBoolean()) { collator.setStrength(Collator.PRIMARY); } ICUCollationDocValuesField collationField = new ICUCollationDocValuesField("collated", collator); doc.add(field); doc.add(collationField); int numDocs = atLeast(500); for (int i = 0; i < numDocs; i++) { String value = TestUtil.randomSimpleString(random()); field.setStringValue(value); collationField.setStringValue(value); iw.addDocument(doc); } IndexReader ir = iw.getReader(); iw.close(); IndexSearcher is = newSearcher(ir); int numChecks = atLeast(100); for (int i = 0; i < numChecks; i++) { String start = TestUtil.randomSimpleString(random()); String end = TestUtil.randomSimpleString(random()); BytesRef lowerVal = new BytesRef(collator.getCollationKey(start).toByteArray()); BytesRef upperVal = new BytesRef(collator.getCollationKey(end).toByteArray()); Query query = new ConstantScoreQuery(FieldCacheRangeFilter.newBytesRefRange("collated", lowerVal, upperVal, true, true)); doTestRanges(is, start, end, query, collator); } ir.close(); dir.close(); }
/** * Returns a Query instance for doing range searches on this field type. {@link org.apache.solr.search.SolrQueryParser} * currently passes part1 and part2 as null if they are '*' respectively. minInclusive and maxInclusive are both true * currently by SolrQueryParser but that may change in the future. Also, other QueryParser implementations may have * different semantics. * <p/> * Sub-classes should override this method to provide their own range query implementation. They should strive to * handle nulls in part1 and/or part2 as well as unequal minInclusive and maxInclusive parameters gracefully. * * @param parser the {@link org.apache.solr.search.QParser} calling the method * @param field the schema field * @param part1 the lower boundary of the range, nulls are allowed. * @param part2 the upper boundary of the range, nulls are allowed * @param minInclusive whether the minimum of the range is inclusive or not * @param maxInclusive whether the maximum of the range is inclusive or not * @return a Query instance to perform range search according to given parameters * */ public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) { // TODO: change these all to use readableToIndexed/bytes instead (e.g. for unicode collation) if (field.hasDocValues() && !field.indexed()) { if (field.multiValued()) { return new ConstantScoreQuery(DocTermOrdsRangeFilter.newBytesRefRange( field.getName(), part1 == null ? null : new BytesRef(toInternal(part1)), part2 == null ? null : new BytesRef(toInternal(part2)), minInclusive, maxInclusive)); } else { return new ConstantScoreQuery(FieldCacheRangeFilter.newStringRange( field.getName(), part1 == null ? null : toInternal(part1), part2 == null ? null : toInternal(part2), minInclusive, maxInclusive)); } } else { MultiTermQuery rangeQuery = TermRangeQuery.newStringRange( field.getName(), part1 == null ? null : toInternal(part1), part2 == null ? null : toInternal(part2), minInclusive, maxInclusive); rangeQuery.setRewriteMethod(getRewriteMethod(parser, field)); return rangeQuery; } }
public void testRanges() throws Exception { Directory dir = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), dir); Document doc = new Document(); Field field = newField("field", "", StringField.TYPE_STORED); Collator collator = Collator.getInstance(); // uses -Dtests.locale if (random().nextBoolean()) { collator.setStrength(Collator.PRIMARY); } ICUCollationDocValuesField collationField = new ICUCollationDocValuesField("collated", collator); doc.add(field); doc.add(collationField); int numDocs = atLeast(500); for (int i = 0; i < numDocs; i++) { String value = _TestUtil.randomSimpleString(random()); field.setStringValue(value); collationField.setStringValue(value); iw.addDocument(doc); } IndexReader ir = iw.getReader(); iw.close(); IndexSearcher is = newSearcher(ir); int numChecks = atLeast(100); for (int i = 0; i < numChecks; i++) { String start = _TestUtil.randomSimpleString(random()); String end = _TestUtil.randomSimpleString(random()); BytesRef lowerVal = new BytesRef(collator.getCollationKey(start).toByteArray()); BytesRef upperVal = new BytesRef(collator.getCollationKey(end).toByteArray()); Query query = new ConstantScoreQuery(FieldCacheRangeFilter.newBytesRefRange("collated", lowerVal, upperVal, true, true)); doTestRanges(is, start, end, query, collator); } ir.close(); dir.close(); }
/** * Returns a Query instance for doing range searches on this field type. {@link org.apache.solr.search.SolrQueryParser} * currently passes part1 and part2 as null if they are '*' respectively. minInclusive and maxInclusive are both true * currently by SolrQueryParser but that may change in the future. Also, other QueryParser implementations may have * different semantics. * <p/> * Sub-classes should override this method to provide their own range query implementation. They should strive to * handle nulls in part1 and/or part2 as well as unequal minInclusive and maxInclusive parameters gracefully. * * @param field the schema field * @param part1 the lower boundary of the range, nulls are allowed. * @param part2 the upper boundary of the range, nulls are allowed * @param minInclusive whether the minimum of the range is inclusive or not * @param maxInclusive whether the maximum of the range is inclusive or not * @return a Query instance to perform range search according to given parameters * */ public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) { // TODO: change these all to use readableToIndexed/bytes instead (e.g. for unicode collation) if (field.hasDocValues() && !field.indexed()) { if (field.multiValued()) { return new ConstantScoreQuery(DocTermOrdsRangeFilter.newBytesRefRange( field.getName(), part1 == null ? null : new BytesRef(toInternal(part1)), part2 == null ? null : new BytesRef(toInternal(part2)), minInclusive, maxInclusive)); } else { return new ConstantScoreQuery(FieldCacheRangeFilter.newStringRange( field.getName(), part1 == null ? null : toInternal(part1), part2 == null ? null : toInternal(part2), minInclusive, maxInclusive)); } } else { MultiTermQuery rangeQuery = TermRangeQuery.newStringRange( field.getName(), part1 == null ? null : toInternal(part1), part2 == null ? null : toInternal(part2), minInclusive, maxInclusive); rangeQuery.setRewriteMethod(getRewriteMethod(parser, field)); return rangeQuery; } }
public void testFieldCacheRangeFilter() throws Exception { Filter filter = FieldCacheRangeFilter.newStringRange("title2", "d", "j", true, true); assertEquals(3, TestUtil.hitCount(searcher, allBooks, filter)); filter = FieldCacheRangeFilter.newIntRange("pubmonth", 201001, 201006, true, true); assertEquals(2, TestUtil.hitCount(searcher, allBooks, filter)); }
/** * Takes a search request and prepares a Lucene Filter object, or null if no * filtering is required. */ protected Collection<Filter> getFilters(Search request) { List<Filter> filters = Lists.newArrayList(); Date[] dateRange = request.getDateRange(); if( dateRange != null ) { filters.add(createDateFilter(FreeTextQuery.FIELD_REALLASTMODIFIED, dateRange, Dates.ISO)); } Collection<com.tle.common.searching.DateFilter> dateFilters = request.getDateFilters(); if( dateFilters != null ) { for( com.tle.common.searching.DateFilter dateFilter : dateFilters ) { Date[] range = dateFilter.getRange(); String indexFieldName = dateFilter.getIndexFieldName(); if( dateFilter.getFormat() == Format.ISO ) { filters.add(createDateFilter(indexFieldName, range, Dates.ISO)); } else { Long start = range[0] != null ? range[0].getTime() : null; Long end = range[1] != null ? range[1].getTime() : null; filters.add(FieldCacheRangeFilter.newLongRange(indexFieldName, start, end, true, true)); } } } String privPrefix = request.getPrivilegePrefix(); String privilege = request.getPrivilege(); if( privPrefix == null && privilege != null ) { privPrefix = getPrefixForPrivilege(privilege); } if( privPrefix != null ) { filters.add(new SecurityFilter(privPrefix)); } List<List<Field>> must = request.getMust(); List<List<Field>> mustNot = request.getMustNot(); if( LOGGER.isDebugEnabled() ) { LOGGER.debug("Must " + must + ": Must Not: " + mustNot + " Privilege:" + privilege); } if( must != null && !must.isEmpty() ) { filters.add(new MustFilter(must)); } if( mustNot != null && !mustNot.isEmpty() ) { filters.add(new MustNotFilter(mustNot)); } List<Field> matrixFields = request.getMatrixFields(); if( matrixFields != null ) { filters.add(new MatrixFilter(matrixFields)); } filters.add(new InstitutionFilter()); return filters; }