SOLR-8396: Add support for PointFields in Solr

This commit is contained in:
Tomas Fernandez Lobbe 2017-01-18 17:27:21 -08:00
parent a89560bb72
commit 57934ba448
49 changed files with 2979 additions and 107 deletions

View File

@ -1073,6 +1073,7 @@
<propertyref prefix="tests.leaveTemporary" />
<propertyref prefix="tests.leavetemporary" />
<propertyref prefix="solr.test.leavetmpdir" />
<propertyref prefix="solr.tests.preferPointFields"/>
</syspropertyset>
<!-- Pass randomized settings to the forked JVM. -->

View File

@ -74,6 +74,10 @@ Optimizations
* SOLR-9584: Support Solr being proxied with another endpoint than default /solr, by using relative links
in AdminUI javascripts (Yun Jie Zhou via janhoy)
Other Changes
----------------------
* SOLR-8396: Add support for PointFields in Solr (Ishan Chattopadhyaya, Tomás Fernández Löbbe)
================== 6.5.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -289,8 +289,6 @@ public class LukeRequestHandler extends RequestHandlerBase
f.add( "schema", getFieldFlags( sfield ) );
f.add( "flags", getFieldFlags( field ) );
Term t = new Term(field.name(), ftype!=null ? ftype.storedToIndexed(field) : field.stringValue());
f.add( "value", (ftype==null)?null:ftype.toExternal( field ) );
// TODO: this really should be "stored"
@ -301,7 +299,10 @@ public class LukeRequestHandler extends RequestHandlerBase
f.add( "binary", Base64.byteArrayToBase64(bytes.bytes, bytes.offset, bytes.length));
}
f.add( "boost", field.boost() );
f.add( "docFreq", t.text()==null ? 0 : reader.docFreq( t ) ); // this can be 0 for non-indexed fields
if (!ftype.isPointField()) {
Term t = new Term(field.name(), ftype!=null ? ftype.storedToIndexed(field) : field.stringValue());
f.add( "docFreq", t.text()==null ? 0 : reader.docFreq( t ) ); // this can be 0 for non-indexed fields
}// TODO: Calculate docFreq for point fields
// If we have a term vector, return that
if( field.fieldType().storeTermVectors() ) {

View File

@ -33,6 +33,7 @@ import java.util.Map.Entry;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
@ -47,6 +48,7 @@ import org.apache.solr.common.util.StrUtils;
import org.apache.solr.request.SimpleFacets;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.PointField;
import org.apache.solr.search.QueryParsing;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.facet.FacetDebugInfo;
@ -1477,7 +1479,13 @@ public class FacetComponent extends SearchComponent {
if (sfc == null) {
sfc = new ShardFacetCount();
sfc.name = name;
sfc.indexed = ftype == null ? sfc.name : ftype.toInternal(sfc.name);
if (ftype == null) {
sfc.indexed = null;
} else if (ftype.isPointField()) {
sfc.indexed = ((PointField)ftype).toInternalByteRef(sfc.name);
} else {
sfc.indexed = new BytesRef(ftype.toInternal(sfc.name));
}
sfc.termNum = termNum++;
counts.put(name, sfc);
}
@ -1553,7 +1561,7 @@ public class FacetComponent extends SearchComponent {
public static class ShardFacetCount {
public String name;
// the indexed form of the name... used for comparisons
public String indexed;
public BytesRef indexed;
public long count;
public int termNum; // term number starting at 0 (used in bit arrays)

View File

@ -185,6 +185,11 @@ public class QueryComponent extends SearchComponent
}
rb.setSortSpec( parser.getSortSpec(true) );
for (SchemaField sf:rb.getSortSpec().getSchemaFields()) {
if (sf != null && sf.getType().isPointField() && !sf.hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,"Can't sort on a point field without docValues");
}
}
rb.setQparser(parser);
final String cursorStr = rb.req.getParams().get(CursorMarkParams.CURSOR_MARK_PARAM);
@ -335,11 +340,21 @@ public class QueryComponent extends SearchComponent
List<String> idArr = StrUtils.splitSmart(ids, ",", true);
int[] luceneIds = new int[idArr.size()];
int docs = 0;
for (int i=0; i<idArr.size(); i++) {
int id = searcher.getFirstMatch(
new Term(idField.getName(), idField.getType().toInternal(idArr.get(i))));
if (id >= 0)
luceneIds[docs++] = id;
if (idField.getType().isPointField()) {
for (int i=0; i<idArr.size(); i++) {
int id = searcher.search(
idField.getType().getFieldQuery(null, idField, idArr.get(i)), 1).scoreDocs[0].doc;
if (id >= 0) {
luceneIds[docs++] = id;
}
}
} else {
for (int i=0; i<idArr.size(); i++) {
int id = searcher.getFirstMatch(
new Term(idField.getName(), idField.getType().toInternal(idArr.get(i))));
if (id >= 0)
luceneIds[docs++] = id;
}
}
DocListAndSet res = new DocListAndSet();

View File

@ -55,7 +55,6 @@ public class RangeFacetProcessor extends SimpleFacets {
*
* @see org.apache.solr.common.params.FacetParams#FACET_RANGE
*/
@SuppressWarnings("unchecked")
public NamedList<Object> getFacetRangeCounts() throws IOException, SyntaxError {
final NamedList<Object> resOuter = new SimpleOrderedMap<>();
@ -92,7 +91,7 @@ public class RangeFacetProcessor extends SimpleFacets {
final FieldType ft = sf.getType();
if (method.equals(FacetRangeMethod.DV)) {
assert ft instanceof TrieField;
assert ft instanceof TrieField || ft.isPointField();
resOuter.add(key, getFacetRangeCountsDocValues(rangeFacetRequest));
} else {
resOuter.add(key, getFacetRangeCounts(rangeFacetRequest));

View File

@ -34,6 +34,7 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.schema.DateRangeField;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.PointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.schema.TrieField;
@ -91,6 +92,11 @@ public class RangeFacetRequest extends FacetComponent.FacetBase {
DateRangeField.class + "'. Will use method '" + FacetParams.FacetRangeMethod.FILTER + "' instead");
method = FacetParams.FacetRangeMethod.FILTER;
}
if (method.equals(FacetParams.FacetRangeMethod.DV) && !schemaField.hasDocValues() && (schemaField.getType().isPointField())) {
log.warn("Range facet method '" + FacetParams.FacetRangeMethod.DV + "' is not supported on PointFields without docValues." +
"Will use method '" + FacetParams.FacetRangeMethod.FILTER + "' instead");
method = FacetParams.FacetRangeMethod.FILTER;
}
this.start = required.getFieldParam(facetOn, FacetParams.FACET_RANGE_START);
this.end = required.getFieldParam(facetOn, FacetParams.FACET_RANGE_END);
@ -159,10 +165,33 @@ public class RangeFacetRequest extends FacetComponent.FacetBase {
default:
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"Unable to range facet on tried field of unexpected type:" + this.facetOn);
"Unable to range facet on Trie field of unexpected type:" + this.facetOn);
}
} else if (ft instanceof DateRangeField) {
calc = new DateRangeEndpointCalculator(this, null);
} else if (ft.isPointField()) {
final PointField pointField = (PointField) ft;
switch (pointField.getType()) {
case FLOAT:
calc = new FloatRangeEndpointCalculator(this);
break;
case DOUBLE:
calc = new DoubleRangeEndpointCalculator(this);
break;
case INTEGER:
calc = new IntegerRangeEndpointCalculator(this);
break;
case LONG:
calc = new LongRangeEndpointCalculator(this);
break;
case DATE:
calc = new DateRangeEndpointCalculator(this, null);
break;
default:
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"Unable to range facet on Point field of unexpected type:" + this.facetOn);
}
} else {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,

View File

@ -45,6 +45,12 @@ public class StatsComponent extends SearchComponent {
rb.setNeedDocSet( true );
rb.doStats = true;
rb._statsInfo = new StatsInfo(rb);
for (StatsField statsField : rb._statsInfo.getStatsFields()) {
if (statsField.getSchemaField() != null && statsField.getSchemaField().getType().isPointField() && !statsField.getSchemaField().hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"Can't calculate stats on a PointField without docValues");
}
}
}
}

View File

@ -65,7 +65,7 @@ public class StatsValuesFactory {
if (TrieDateField.class.isInstance(fieldType)) {
return new DateStatsValues(statsField);
} else if (TrieField.class.isInstance(fieldType)) {
} else if (TrieField.class.isInstance(fieldType) || PointField.class.isInstance(fieldType)) {
return new NumericStatsValues(statsField);
} else if (StrField.class.isInstance(fieldType)) {
return new StringStatsValues(statsField);

View File

@ -65,9 +65,6 @@ public final class SlowCompositeReaderWrapper extends LeafReader {
SlowCompositeReaderWrapper(CompositeReader reader, boolean merging) throws IOException {
super();
in = reader;
if (getFieldInfos().hasPointValues()) {
throw new IllegalArgumentException("cannot wrap points");
}
fields = MultiFields.getFields(in);
in.registerParentReader(this);
this.merging = merging;

View File

@ -42,6 +42,7 @@ import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.IntervalFacets.FacetInterval;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.PointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.search.DocIterator;
@ -625,6 +626,9 @@ public class IntervalFacets implements Iterable<FacetInterval> {
if ("*".equals(value)) {
return null;
}
if (schemaField.getType().isPointField()) {
return ((PointField)schemaField.getType()).toInternalByteRef(value);
}
return new BytesRef(schemaField.getType().toInternal(value));
}

View File

@ -411,6 +411,10 @@ public class SimpleFacets {
NamedList<Integer> counts;
SchemaField sf = searcher.getSchema().getField(field);
if (sf.getType().isPointField() && !sf.hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"Can't facet on a PointField without docValues");
}
FieldType ft = sf.getType();
// determine what type of faceting method to use
@ -579,6 +583,10 @@ public class SimpleFacets {
static FacetMethod selectFacetMethod(SchemaField field, FacetMethod method, Integer mincount) {
FieldType type = field.getType();
if (type.isPointField()) {
// Only FCS is supported for PointFields for now
return FacetMethod.FCS;
}
/*The user did not specify any preference*/
if (method == null) {
@ -810,12 +818,20 @@ public class SimpleFacets {
* @param terms a list of term values (in the specified field) to compute the counts for
*/
protected NamedList<Integer> getListedTermCounts(String field, final ParsedParams parsed, List<String> terms) throws IOException {
FieldType ft = searcher.getSchema().getFieldType(field);
SchemaField sf = searcher.getSchema().getField(field);
FieldType ft = sf.getType();
NamedList<Integer> res = new NamedList<>();
for (String term : terms) {
String internal = ft.toInternal(term);
int count = searcher.numDocs(new TermQuery(new Term(field, internal)), parsed.docs);
res.add(term, count);
if (ft.isPointField()) {
for (String term : terms) {
int count = searcher.numDocs(ft.getFieldQuery(null, sf, term), parsed.docs);
res.add(term, count);
}
} else {
for (String term : terms) {
String internal = ft.toInternal(term);
int count = searcher.numDocs(new TermQuery(new Term(field, internal)), parsed.docs);
res.add(term, count);
}
}
return res;
}
@ -848,7 +864,7 @@ public class SimpleFacets {
public NamedList<Integer> getFacetTermEnumCounts(SolrIndexSearcher searcher, DocSet docs, String field, int offset, int limit, int mincount, boolean missing,
String sort, String prefix, String contains, boolean ignoreCase, boolean intersectsCheck)
throws IOException {
/* :TODO: potential optimization...
* cache the Terms with the highest docFreq and try them first
* don't enum if we get our max from them
@ -864,10 +880,12 @@ public class SimpleFacets {
fastForRandomSet = new HashDocSet(sset.getDocs(), 0, sset.size());
}
IndexSchema schema = searcher.getSchema();
LeafReader r = searcher.getSlowAtomicReader();
FieldType ft = schema.getFieldType(field);
assert !ft.isPointField(): "Point Fields don't support enum method";
LeafReader r = searcher.getSlowAtomicReader();
boolean sortByCount = sort.equals("count") || sort.equals("true");
final int maxsize = limit>=0 ? offset+limit : Integer.MAX_VALUE-1;
@ -1082,6 +1100,9 @@ public class SimpleFacets {
if (parsed.params.getBool(GroupParams.GROUP_FACET, false)) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Interval Faceting can't be used with " + GroupParams.GROUP_FACET);
}
if (schemaField.getType().isPointField() && !schemaField.hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can't use interval faceting on a PointField without docValues");
}
SimpleOrderedMap<Integer> fieldResults = new SimpleOrderedMap<Integer>();
res.add(parsed.key, fieldResults);

View File

@ -31,8 +31,12 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.response.transform.DocTransformer;
import org.apache.solr.schema.BinaryField;
import org.apache.solr.schema.BoolField;
import org.apache.solr.schema.DoublePointField;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.FloatPointField;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.IntPointField;
import org.apache.solr.schema.LongPointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.StrField;
import org.apache.solr.schema.TextField;
@ -213,6 +217,10 @@ public class DocsStreamer implements Iterator<SolrDocument> {
KNOWN_TYPES.add(TrieDoubleField.class);
KNOWN_TYPES.add(TrieDateField.class);
KNOWN_TYPES.add(BinaryField.class);
KNOWN_TYPES.add(IntPointField.class);
KNOWN_TYPES.add(LongPointField.class);
KNOWN_TYPES.add(DoublePointField.class);
KNOWN_TYPES.add(FloatPointField.class);
// We do not add UUIDField because UUID object is not a supported type in JavaBinCodec
// and if we write UUIDField.toObject, we wouldn't know how to handle it in the client side
}

View File

@ -0,0 +1,187 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.legacy.LegacyNumericType;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.solr.search.QParser;
import org.apache.solr.uninverting.UninvertingReader.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@code PointField} implementation for {@code Double} values.
* @see PointField
* @see DoublePoint
*/
public class DoublePointField extends PointField implements DoubleValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
if (val instanceof Number) return ((Number) val).doubleValue();
if (val instanceof String) return Double.parseDouble((String) val);
return super.toNativeType(val);
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
double actualMin, actualMax;
if (min == null) {
actualMin = Double.NEGATIVE_INFINITY;
} else {
actualMin = Double.parseDouble(min);
if (!minInclusive) {
actualMin = DoublePoint.nextUp(actualMin);
}
}
if (max == null) {
actualMax = Double.POSITIVE_INFINITY;
} else {
actualMax = Double.parseDouble(max);
if (!maxInclusive) {
actualMax = DoublePoint.nextDown(actualMax);
}
}
return DoublePoint.newRangeQuery(field.getName(), actualMin, actualMax);
}
@Override
public Object toObject(SchemaField sf, BytesRef term) {
return DoublePoint.decodeDimension(term.bytes, term.offset);
}
@Override
public Object toObject(IndexableField f) {
final Number val = f.numericValue();
if (val != null) {
if (f.fieldType().stored() == false && f.fieldType().docValuesType() == DocValuesType.NUMERIC) {
return Double.longBitsToDouble(val.longValue());
} else {
return val;
}
} else {
throw new AssertionError("Unexpected state. Field: '" + f + "'");
}
}
@Override
protected Query getExactQuery(SchemaField field, String externalVal) {
return DoublePoint.newExactQuery(field.getName(), Double.parseDouble(externalVal));
}
@Override
public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
assert externalVal.size() > 0;
double[] values = new double[externalVal.size()];
int i = 0;
for (String val:externalVal) {
values[i] = Double.parseDouble(val);
i++;
}
return DoublePoint.newSetQuery(field.getName(), values);
}
@Override
protected String indexedToReadable(BytesRef indexedForm) {
return Double.toString(DoublePoint.decodeDimension(indexedForm.bytes, indexedForm.offset));
}
@Override
public void readableToIndexed(CharSequence val, BytesRefBuilder result) {
result.grow(Double.BYTES);
result.setLength(Double.BYTES);
DoublePoint.encodeDimension(Double.parseDouble(val.toString()), result.bytes(), 0);
}
@Override
public SortField getSortField(SchemaField field, boolean top) {
field.checkSortability();
Object missingValue = null;
boolean sortMissingLast = field.sortMissingLast();
boolean sortMissingFirst = field.sortMissingFirst();
if (sortMissingLast) {
missingValue = top ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
} else if (sortMissingFirst) {
missingValue = top ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
}
SortField sf = new SortField(field.getName(), SortField.Type.DOUBLE, top);
sf.setMissingValue(missingValue);
return sf;
}
@Override
public Type getUninversionType(SchemaField sf) {
if (sf.multiValued()) {
throw new UnsupportedOperationException("MultiValued Point fields with DocValues is not currently supported");
// return Type.SORTED_DOUBLE;
} else {
return Type.DOUBLE_POINT;
}
}
@Override
public ValueSource getValueSource(SchemaField field, QParser qparser) {
field.checkFieldCacheSource();
return new DoubleFieldSource(field.getName());
}
@Override
public LegacyNumericType getNumericType() {
// TODO: refactor this to not use LegacyNumericType
return LegacyNumericType.DOUBLE;
}
@Override
public IndexableField createField(SchemaField field, Object value, float boost) {
if (!isFieldUsed(field)) return null;
if (boost != 1.0 && log.isTraceEnabled()) {
log.trace("Can't use document/field boost for PointField. Field: " + field.getName() + ", boost: " + boost);
}
double doubleValue = (value instanceof Number) ? ((Number) value).doubleValue() : Double.parseDouble(value.toString());
return new DoublePoint(field.getName(), doubleValue);
}
@Override
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Double) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.DOUBLE;
}
}

View File

@ -126,6 +126,10 @@ public abstract class FieldType extends FieldProperties {
public boolean isPolyField(){
return false;
}
public boolean isPointField() {
return false;
}
/**
* Returns true if the fields' docValues should be used for obtaining stored value
@ -395,7 +399,10 @@ public abstract class FieldType extends FieldProperties {
return toInternal(val);
}
/** Given the readable value, return the term value that will match it. */
/** Given the readable value, return the term value that will match it.
* This method will modify the size and length of the {@code result}
* parameter and write from offset 0
*/
public void readableToIndexed(CharSequence val, BytesRefBuilder result) {
final String internal = readableToIndexed(val.toString());
result.copyChars(internal);

View File

@ -0,0 +1,187 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.legacy.LegacyNumericType;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.solr.search.QParser;
import org.apache.solr.uninverting.UninvertingReader.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@code PointField} implementation for {@code Float} values.
* @see PointField
* @see FloatPoint
*/
public class FloatPointField extends PointField implements FloatValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
if (val instanceof Number) return ((Number) val).floatValue();
if (val instanceof String) return Float.parseFloat((String) val);
return super.toNativeType(val);
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
float actualMin, actualMax;
if (min == null) {
actualMin = Float.NEGATIVE_INFINITY;
} else {
actualMin = Float.parseFloat(min);
if (!minInclusive) {
actualMin = FloatPoint.nextUp(actualMin);
}
}
if (max == null) {
actualMax = Float.POSITIVE_INFINITY;
} else {
actualMax = Float.parseFloat(max);
if (!maxInclusive) {
actualMax = FloatPoint.nextDown(actualMax);
}
}
return FloatPoint.newRangeQuery(field.getName(), actualMin, actualMax);
}
@Override
public Object toObject(SchemaField sf, BytesRef term) {
return FloatPoint.decodeDimension(term.bytes, term.offset);
}
@Override
public Object toObject(IndexableField f) {
final Number val = f.numericValue();
if (val != null) {
if (f.fieldType().stored() == false && f.fieldType().docValuesType() == DocValuesType.NUMERIC) {
return Float.intBitsToFloat(val.intValue());
} else {
return val;
}
} else {
throw new AssertionError("Unexpected state. Field: '" + f + "'");
}
}
@Override
protected Query getExactQuery(SchemaField field, String externalVal) {
return FloatPoint.newExactQuery(field.getName(), Float.parseFloat(externalVal));
}
@Override
public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
assert externalVal.size() > 0;
float[] values = new float[externalVal.size()];
int i = 0;
for (String val:externalVal) {
values[i] = Float.parseFloat(val);
i++;
}
return FloatPoint.newSetQuery(field.getName(), values);
}
@Override
protected String indexedToReadable(BytesRef indexedForm) {
return Float.toString(FloatPoint.decodeDimension(indexedForm.bytes, indexedForm.offset));
}
@Override
public void readableToIndexed(CharSequence val, BytesRefBuilder result) {
result.grow(Float.BYTES);
result.setLength(Float.BYTES);
FloatPoint.encodeDimension(Float.parseFloat(val.toString()), result.bytes(), 0);
}
@Override
public SortField getSortField(SchemaField field, boolean top) {
field.checkSortability();
Object missingValue = null;
boolean sortMissingLast = field.sortMissingLast();
boolean sortMissingFirst = field.sortMissingFirst();
if (sortMissingLast) {
missingValue = top ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
} else if (sortMissingFirst) {
missingValue = top ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
}
SortField sf = new SortField(field.getName(), SortField.Type.FLOAT, top);
sf.setMissingValue(missingValue);
return sf;
}
@Override
public Type getUninversionType(SchemaField sf) {
if (sf.multiValued()) {
throw new UnsupportedOperationException("MultiValued Point fields with DocValues is not currently supported");
// return Type.SORTED_FLOAT;
} else {
return Type.FLOAT_POINT;
}
}
@Override
public ValueSource getValueSource(SchemaField field, QParser qparser) {
field.checkFieldCacheSource();
return new FloatFieldSource(field.getName());
}
@Override
public LegacyNumericType getNumericType() {
// TODO: refactor this to not use LegacyNumericType
return LegacyNumericType.FLOAT;
}
@Override
public IndexableField createField(SchemaField field, Object value, float boost) {
if (!isFieldUsed(field)) return null;
if (boost != 1.0 && log.isTraceEnabled()) {
log.trace("Can't use document/field boost for PointField. Field: " + field.getName() + ", boost: " + boost);
}
float floatValue = (value instanceof Number) ? ((Number) value).floatValue() : Float.parseFloat(value.toString());
return new FloatPoint(field.getName(), floatValue);
}
@Override
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Float) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.FLOAT;
}
}

View File

@ -0,0 +1,186 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.legacy.LegacyNumericType;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.IntFieldSource;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.solr.search.QParser;
import org.apache.solr.uninverting.UninvertingReader.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@code PointField} implementation for {@code Integer} values.
* @see PointField
* @see IntPoint
*/
public class IntPointField extends PointField implements IntValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
if (val instanceof Number) return ((Number) val).intValue();
try {
if (val instanceof String) return Integer.parseInt((String) val);
} catch (NumberFormatException e) {
Float v = Float.parseFloat((String) val);
return v.intValue();
}
return super.toNativeType(val);
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
int actualMin, actualMax;
if (min == null) {
actualMin = Integer.MIN_VALUE;
} else {
actualMin = Integer.parseInt(min);
if (!minInclusive) {
actualMin++;
}
}
if (max == null) {
actualMax = Integer.MAX_VALUE;
} else {
actualMax = Integer.parseInt(max);
if (!maxInclusive) {
actualMax--;
}
}
return IntPoint.newRangeQuery(field.getName(), actualMin, actualMax);
}
@Override
public Object toObject(SchemaField sf, BytesRef term) {
return IntPoint.decodeDimension(term.bytes, term.offset);
}
@Override
public Object toObject(IndexableField f) {
final Number val = f.numericValue();
if (val != null) {
return val;
} else {
throw new AssertionError("Unexpected state. Field: '" + f + "'");
}
}
@Override
protected Query getExactQuery(SchemaField field, String externalVal) {
return IntPoint.newExactQuery(field.getName(), Integer.parseInt(externalVal));
}
@Override
public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
assert externalVal.size() > 0;
int[] values = new int[externalVal.size()];
int i = 0;
for (String val:externalVal) {
values[i] = Integer.parseInt(val);
i++;
}
return IntPoint.newSetQuery(field.getName(), values);
}
@Override
protected String indexedToReadable(BytesRef indexedForm) {
return Integer.toString(IntPoint.decodeDimension(indexedForm.bytes, indexedForm.offset));
}
@Override
public void readableToIndexed(CharSequence val, BytesRefBuilder result) {
result.grow(Integer.BYTES);
result.setLength(Integer.BYTES);
IntPoint.encodeDimension(Integer.parseInt(val.toString()), result.bytes(), 0);
}
@Override
public SortField getSortField(SchemaField field, boolean top) {
field.checkSortability();
Object missingValue = null;
boolean sortMissingLast = field.sortMissingLast();
boolean sortMissingFirst = field.sortMissingFirst();
if (sortMissingLast) {
missingValue = top ? Integer.MIN_VALUE : Integer.MAX_VALUE;
} else if (sortMissingFirst) {
missingValue = top ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
SortField sf = new SortField(field.getName(), SortField.Type.INT, top);
sf.setMissingValue(missingValue);
return sf;
}
@Override
public Type getUninversionType(SchemaField sf) {
if (sf.multiValued()) {
throw new UnsupportedOperationException("MultiValued Point fields with DocValues is not currently supported");
// return Type.SORTED_INTEGER;
} else {
return Type.INTEGER_POINT;
}
}
@Override
public ValueSource getValueSource(SchemaField field, QParser qparser) {
field.checkFieldCacheSource();
return new IntFieldSource(field.getName());
}
@Override
public LegacyNumericType getNumericType() {
return LegacyNumericType.INT;
}
@Override
public IndexableField createField(SchemaField field, Object value, float boost) {
if (!isFieldUsed(field)) return null;
if (boost != 1.0 && log.isTraceEnabled()) {
log.trace("Can't use document/field boost for PointField. Field: " + field.getName() + ", boost: " + boost);
}
int intValue = (value instanceof Number) ? ((Number) value).intValue() : Integer.parseInt(value.toString());
return new IntPoint(field.getName(), intValue);
}
@Override
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Integer) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.INTEGER;
}
}

View File

@ -0,0 +1,186 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.legacy.LegacyNumericType;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.solr.search.QParser;
import org.apache.solr.uninverting.UninvertingReader.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@code PointField} implementation for {@code Long} values.
* @see PointField
* @see LongPoint
*/
public class LongPointField extends PointField implements LongValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
if (val instanceof Number) return ((Number) val).longValue();
try {
if (val instanceof String) return Long.parseLong((String) val);
} catch (NumberFormatException e) {
Double v = Double.parseDouble((String) val);
return v.longValue();
}
return super.toNativeType(val);
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
long actualMin, actualMax;
if (min == null) {
actualMin = Long.MIN_VALUE;
} else {
actualMin = Long.parseLong(min);
if (!minInclusive) {
actualMin++;
}
}
if (max == null) {
actualMax = Long.MAX_VALUE;
} else {
actualMax = Long.parseLong(max);
if (!maxInclusive) {
actualMax--;
}
}
return LongPoint.newRangeQuery(field.getName(), actualMin, actualMax);
}
@Override
public Object toObject(SchemaField sf, BytesRef term) {
return LongPoint.decodeDimension(term.bytes, term.offset);
}
@Override
public Object toObject(IndexableField f) {
final Number val = f.numericValue();
if (val != null) {
return val;
} else {
throw new AssertionError("Unexpected state. Field: '" + f + "'");
}
}
@Override
protected Query getExactQuery(SchemaField field, String externalVal) {
return LongPoint.newExactQuery(field.getName(), Long.parseLong(externalVal));
}
@Override
public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
assert externalVal.size() > 0;
long[] values = new long[externalVal.size()];
int i = 0;
for (String val:externalVal) {
values[i] = Long.parseLong(val);
i++;
}
return LongPoint.newSetQuery(field.getName(), values);
}
@Override
protected String indexedToReadable(BytesRef indexedForm) {
return Long.toString(LongPoint.decodeDimension(indexedForm.bytes, indexedForm.offset));
}
@Override
public void readableToIndexed(CharSequence val, BytesRefBuilder result) {
result.grow(Long.BYTES);
result.setLength(Long.BYTES);
LongPoint.encodeDimension(Long.parseLong(val.toString()), result.bytes(), 0);
}
@Override
public SortField getSortField(SchemaField field, boolean top) {
field.checkSortability();
Object missingValue = null;
boolean sortMissingLast = field.sortMissingLast();
boolean sortMissingFirst = field.sortMissingFirst();
if (sortMissingLast) {
missingValue = top ? Long.MIN_VALUE : Long.MAX_VALUE;
} else if (sortMissingFirst) {
missingValue = top ? Long.MAX_VALUE : Long.MIN_VALUE;
}
SortField sf = new SortField(field.getName(), SortField.Type.LONG, top);
sf.setMissingValue(missingValue);
return sf;
}
@Override
public Type getUninversionType(SchemaField sf) {
if (sf.multiValued()) {
throw new UnsupportedOperationException("MultiValued Point fields with DocValues is not currently supported");
// return Type.SORTED_LONG;
} else {
return Type.LONG_POINT;
}
}
@Override
public ValueSource getValueSource(SchemaField field, QParser qparser) {
field.checkFieldCacheSource();
return new LongFieldSource(field.getName());
}
@Override
public LegacyNumericType getNumericType() {
return LegacyNumericType.LONG;
}
@Override
public IndexableField createField(SchemaField field, Object value, float boost) {
if (!isFieldUsed(field)) return null;
if (boost != 1.0 && log.isTraceEnabled()) {
log.trace("Can't use document/field boost for PointField. Field: " + field.getName() + ", boost: " + boost);
}
long longValue = (value instanceof Number) ? ((Number) value).longValue() : Long.parseLong(value.toString());
return new LongPoint(field.getName(), longValue);
}
@Override
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Long) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.LONG;
}
}

View File

@ -0,0 +1,233 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortedSetSelector;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRef;
import org.apache.lucene.util.CharsRefBuilder;
import org.apache.solr.common.SolrException;
import org.apache.solr.response.TextResponseWriter;
import org.apache.solr.search.QParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides field types to support for Lucene's {@link
* org.apache.lucene.document.IntPoint}, {@link org.apache.lucene.document.LongPoint}, {@link org.apache.lucene.document.FloatPoint} and
* {@link org.apache.lucene.document.DoublePoint}.
* See {@link org.apache.lucene.search.PointRangeQuery} for more details.
* It supports integer, float, long and double types. See subclasses for details.
* <br>
* {@code DocValues} are supported for single-value cases ({@code NumericDocValues}).
* {@code FieldCache} is not supported for {@code PointField}s, so sorting, faceting, etc on these fields require the use of {@code docValues="true"} in the schema.
*/
public abstract class PointField extends PrimitiveFieldType {
public enum PointTypes {
INTEGER,
LONG,
FLOAT,
DOUBLE,
DATE
}
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public boolean isPointField() {
return true;
}
@Override
public final ValueSource getSingleValueSource(MultiValueSelector choice, SchemaField field, QParser parser) {
// trivial base case
if (!field.multiValued()) {
// single value matches any selector
return getValueSource(field, parser);
}
// Point fields don't support UninvertingReader. See SOLR-9202
if (!field.hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"docValues='true' is required to select '" + choice.toString() +
"' value from multivalued field ("+ field.getName() +") at query time");
}
// multivalued Point fields all use SortedSetDocValues, so we give a clean error if that's
// not supported by the specified choice, else we delegate to a helper
SortedSetSelector.Type selectorType = choice.getSortedSetSelectorType();
if (null == selectorType) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
choice.toString() + " is not a supported option for picking a single value"
+ " from the multivalued field: " + field.getName() +
" (type: " + this.getTypeName() + ")");
}
return getSingleValueSource(selectorType, field);
}
/**
* Helper method that will only be called for multivalued Point fields that have doc values.
* Default impl throws an error indicating that selecting a single value from this multivalued
* field is not supported for this field type
*
* @param choice the selector Type to use, will never be null
* @param field the field to use, guaranteed to be multivalued.
* @see #getSingleValueSource(MultiValueSelector,SchemaField,QParser)
*/
protected ValueSource getSingleValueSource(SortedSetSelector.Type choice, SchemaField field) {
throw new UnsupportedOperationException("MultiValued Point fields with DocValues is not currently supported");
}
@Override
public boolean isTokenized() {
return false;
}
@Override
public boolean multiValuedFieldCache() {
return false;
}
/**
* @return the type of this field
*/
public abstract PointTypes getType();
@Override
public abstract Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVals);
@Override
public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) {
if (!field.indexed() && field.hasDocValues()) {
// currently implemented as singleton range
return getRangeQuery(parser, field, externalVal, externalVal, true, true);
} else {
return getExactQuery(field, externalVal);
}
}
protected abstract Query getExactQuery(SchemaField field, String externalVal);
@Override
public String storedToReadable(IndexableField f) {
return toExternal(f);
}
@Override
public String toInternal(String val) {
throw new UnsupportedOperationException("Can't generate internal string in PointField. use PointField.toInternalByteRef");
}
public BytesRef toInternalByteRef(String val) {
final BytesRefBuilder bytes = new BytesRefBuilder();
readableToIndexed(val, bytes);
return bytes.get();
}
@Override
public void write(TextResponseWriter writer, String name, IndexableField f) throws IOException {
writer.writeVal(name, toObject(f));
}
@Override
public String storedToIndexed(IndexableField f) {
throw new UnsupportedOperationException("Not supported with PointFields");
}
@Override
public CharsRef indexedToReadable(BytesRef indexedForm, CharsRefBuilder charsRef) {
final String value = indexedToReadable(indexedForm);
charsRef.grow(value.length());
charsRef.setLength(value.length());
value.getChars(0, charsRef.length(), charsRef.chars(), 0);
return charsRef.get();
}
@Override
public String indexedToReadable(String indexedForm) {
return indexedToReadable(new BytesRef(indexedForm));
}
protected abstract String indexedToReadable(BytesRef indexedForm);
protected boolean isFieldUsed(SchemaField field) {
boolean indexed = field.indexed();
boolean stored = field.stored();
boolean docValues = field.hasDocValues();
if (!indexed && !stored && !docValues) {
if (log.isTraceEnabled()) {
log.trace("Ignoring unindexed/unstored field: " + field);
}
return false;
}
return true;
}
@Override
public List<IndexableField> createFields(SchemaField sf, Object value, float boost) {
if (!(sf.hasDocValues() || sf.stored())) {
return Collections.singletonList(createField(sf, value, boost));
}
List<IndexableField> fields = new ArrayList<>();
final IndexableField field = createField(sf, value, boost);
fields.add(field);
if (sf.hasDocValues()) {
if (sf.multiValued()) {
throw new UnsupportedOperationException("MultiValued Point fields with DocValues is not currently supported. Field: '" + sf.getName() + "'");
} else {
final long bits;
if (field.numericValue() instanceof Integer || field.numericValue() instanceof Long) {
bits = field.numericValue().longValue();
} else if (field.numericValue() instanceof Float) {
bits = Float.floatToIntBits(field.numericValue().floatValue());
} else {
assert field.numericValue() instanceof Double;
bits = Double.doubleToLongBits(field.numericValue().doubleValue());
}
fields.add(new NumericDocValuesField(sf.getName(), bits));
}
}
if (sf.stored()) {
fields.add(getStoredField(sf, value));
}
return fields;
}
protected abstract StoredField getStoredField(SchemaField sf, Object value);
@Override
public void checkSchemaField(final SchemaField field) {
// PointFields support DocValues
}
}

View File

@ -170,6 +170,11 @@ public final class SchemaField extends FieldProperties implements IndexableField
"can not sort on multivalued field: "
+ getName());
}
if (this.type.isPointField() && !hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"can not sort on a PointField without doc values: "
+ getName());
}
}
/**
@ -191,6 +196,11 @@ public final class SchemaField extends FieldProperties implements IndexableField
"can not use FieldCache on multivalued field: "
+ getName());
}
if (this.type.isPointField() && !hasDocValues()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"Point fields can't use FieldCache. Use docValues=true for field: "
+ getName());
}
}

View File

@ -98,6 +98,7 @@ import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.BoolField;
import org.apache.solr.schema.EnumField;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.PointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.schema.TrieDoubleField;
@ -821,16 +822,39 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
continue;
}
Object newVal = val;
if (schemaField.getType() instanceof TrieIntField) {
newVal = val.intValue();
} else if (schemaField.getType() instanceof TrieFloatField) {
newVal = Float.intBitsToFloat(val.intValue());
} else if (schemaField.getType() instanceof TrieDoubleField) {
newVal = Double.longBitsToDouble(val);
} else if (schemaField.getType() instanceof TrieDateField) {
newVal = new Date(val);
} else if (schemaField.getType() instanceof EnumField) {
newVal = ((EnumField) schemaField.getType()).intValueToStringValue(val.intValue());
if (schemaField.getType().isPointField()) {
PointField.PointTypes type = ((PointField)schemaField.getType()).getType();
switch (type) {
case INTEGER:
newVal = val.intValue();
break;
case LONG:
newVal = val.longValue();
break;
case FLOAT:
newVal = Float.intBitsToFloat(val.intValue());
break;
case DOUBLE:
newVal = Double.longBitsToDouble(val);
break;
case DATE:
newVal = new Date(val);
break;
default:
throw new AssertionError("Unexpected PointType: " + type);
}
} else {
if (schemaField.getType() instanceof TrieIntField) {
newVal = val.intValue();
} else if (schemaField.getType() instanceof TrieFloatField) {
newVal = Float.intBitsToFloat(val.intValue());
} else if (schemaField.getType() instanceof TrieDoubleField) {
newVal = Double.longBitsToDouble(val);
} else if (schemaField.getType() instanceof TrieDateField) {
newVal = new Date(val);
} else if (schemaField.getType() instanceof EnumField) {
newVal = ((EnumField) schemaField.getType()).intValueToStringValue(val.intValue());
}
}
doc.addField(fieldName, newVal);
break;

View File

@ -50,10 +50,16 @@ public class TermQParserPlugin extends QParserPlugin {
String fname = localParams.get(QueryParsing.F);
FieldType ft = req.getSchema().getFieldTypeNoEx(fname);
String val = localParams.get(QueryParsing.V);
BytesRefBuilder term = new BytesRefBuilder();
BytesRefBuilder term;
if (ft != null) {
ft.readableToIndexed(val, term);
if (ft.isPointField()) {
return ft.getFieldQuery(this, req.getSchema().getField(fname), val);
} else {
term = new BytesRefBuilder();
ft.readableToIndexed(val, term);
}
} else {
term = new BytesRefBuilder();
term.copyChars(val);
}
return new TermQuery(new Term(fname, term.get()));

View File

@ -17,6 +17,7 @@
package org.apache.solr.search;
import java.util.Arrays;
import java.util.Locale;
import java.util.regex.Pattern;
import org.apache.lucene.index.Term;
@ -35,6 +36,7 @@ import org.apache.lucene.util.automaton.Automaton;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.PointField;
/**
* Finds documents whose specified field has any of the specified values. It's like
@ -110,6 +112,14 @@ public class TermsQParserPlugin extends QParserPlugin {
return new MatchNoDocsQuery();
final String[] splitVals = sepIsSpace ? qstr.split("\\s+") : qstr.split(Pattern.quote(separator), -1);
assert splitVals.length > 0;
if (ft.isPointField()) {
if (localParams.get(METHOD) != null) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "Method '%s' not supported in TermsQParser when using PointFields", localParams.get(METHOD)));
}
return ((PointField)ft).getSetQuery(this, req.getSchema().getField(fname), Arrays.asList(splitVals));
}
BytesRef[] bytesRefs = new BytesRef[splitVals.length];
BytesRefBuilder term = new BytesRefBuilder();

View File

@ -30,6 +30,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.FacetParams;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.PointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
import org.apache.solr.schema.TrieField;
@ -141,7 +142,32 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
(SolrException.ErrorCode.BAD_REQUEST,
"Expected numeric field type :" + sf);
}
} else {
} else if (ft instanceof PointField) {
final PointField pfield = (PointField)ft;
switch (pfield.getType()) {
case FLOAT:
calc = new FloatCalc(sf);
break;
case DOUBLE:
calc = new DoubleCalc(sf);
break;
case INTEGER:
calc = new IntCalc(sf);
break;
case LONG:
calc = new LongCalc(sf);
break;
case DATE:
calc = new DateCalc(sf, null);
break;
default:
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"Expected numeric field type :" + sf);
}
}
else {
throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST,
"Expected numeric field type :" + sf);

View File

@ -28,7 +28,11 @@ import org.apache.lucene.search.SortField;
import org.apache.lucene.search.spell.Dictionary;
import org.apache.lucene.search.suggest.DocumentValueSourceDictionary;
import org.apache.solr.core.SolrCore;
import org.apache.solr.schema.DoublePointField;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.FloatPointField;
import org.apache.solr.schema.IntPointField;
import org.apache.solr.schema.LongPointField;
import org.apache.solr.schema.TrieDoubleField;
import org.apache.solr.schema.TrieFloatField;
import org.apache.solr.schema.TrieIntField;
@ -111,13 +115,13 @@ public class DocumentExpressionDictionaryFactory extends DictionaryFactory {
SortField.Type type = null;
String fieldTypeName = core.getLatestSchema().getField(sortFieldName).getType().getTypeName();
FieldType ft = core.getLatestSchema().getFieldTypes().get(fieldTypeName);
if (ft instanceof TrieFloatField) {
if (ft instanceof TrieFloatField || ft instanceof FloatPointField) {
type = SortField.Type.FLOAT;
} else if (ft instanceof TrieIntField) {
} else if (ft instanceof TrieIntField || ft instanceof IntPointField) {
type = SortField.Type.INT;
} else if (ft instanceof TrieLongField) {
} else if (ft instanceof TrieLongField || ft instanceof LongPointField) {
type = SortField.Type.LONG;
} else if (ft instanceof TrieDoubleField) {
} else if (ft instanceof TrieDoubleField || ft instanceof DoublePointField) {
type = SortField.Type.DOUBLE;
}
return type;

View File

@ -24,12 +24,18 @@
<fieldType name="date" class="solr.TrieDateField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true"/>
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
<!-- Point Fields -->
<fieldType name="pint" class="solr.IntPointField" docValues="true"/>
<fieldType name="plong" class="solr.LongPointField" docValues="true"/>
<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
<fieldType name="pfloat" class="solr.FloatPointField" docValues="true"/>
<field name="id" type="string" indexed="true" stored="true" docValues="false" multiValued="false" required="true"/>
<field name="id_dv" type="string" indexed="false" stored="false" docValues="true" multiValued="false"
required="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_i_dv" type="int" indexed="false" stored="false" docValues="true"/>
<dynamicField name="*_i_dv" type="${solr.tests.intClass:pint}" indexed="false" stored="false" docValues="true"/>
<dynamicField name="*_is" type="int" indexed="true" stored="false" docValues="false" multiValued="true"/>
<dynamicField name="*_is_dv" type="int" indexed="false" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="false" docValues="false"/>
@ -37,13 +43,13 @@
<dynamicField name="*_ss" type="string" indexed="true" stored="false" docValues="false" multiValued="true"/>
<dynamicField name="*_ss_dv" type="string" indexed="false" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_f_dv" type="float" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_f_dv" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_fs_dv" type="float" indexed="true" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_l_dv" type="long" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_l_dv" type="${solr.tests.longClass:plong}" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_ls_dv" type="long" indexed="true" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_d_dv" type="double" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_d_dv" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_ds_dv" type="double" indexed="true" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_dt_dv" type="date" indexed="true" stored="false" docValues="true"/>

View File

@ -23,12 +23,17 @@
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="date" class="solr.TrieDateField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true"/>
<fieldType name="pint" class="solr.IntPointField"/>
<fieldType name="plong" class="solr.LongPointField"/>
<fieldType name="pdouble" class="solr.DoublePointField"/>
<fieldType name="pfloat" class="solr.FloatPointField"/>
<field name="id" type="string" indexed="true" stored="true" docValues="false" multiValued="false" required="true"/>
<field name="id_dv" type="string" indexed="false" stored="false" docValues="true" multiValued="false"
required="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_i_dv" type="int" indexed="false" stored="false" docValues="true"/>
<dynamicField name="*_i_p" type="pint" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_is" type="int" indexed="true" stored="false" docValues="false" multiValued="true"/>
<dynamicField name="*_is_dv" type="int" indexed="false" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="false" docValues="false"/>
@ -37,14 +42,17 @@
<dynamicField name="*_ss_dv" type="string" indexed="false" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_f_dv" type="float" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_f_p" type="pfloat" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_fs" type="float" indexed="true" stored="false" docValues="false" multiValued="true"/>
<dynamicField name="*_fs_dv" type="float" indexed="true" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_l_dv" type="long" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_l_p" type="plong" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_ls" type="long" indexed="true" stored="false" docValues="false" multiValued="true"/>
<dynamicField name="*_ls_dv" type="long" indexed="true" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="false" docValues="false"/>
<dynamicField name="*_d_dv" type="double" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_d_p" type="pdouble" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_ds" type="double" indexed="true" stored="false" docValues="false" multiValued="true"/>
<dynamicField name="*_ds_dv" type="double" indexed="true" stored="false" docValues="true" multiValued="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="false" docValues="false"/>
@ -55,11 +63,15 @@
<uniqueKey>id</uniqueKey>
<copyField source="*_i" dest="*_i_dv"/>
<copyField source="*_i" dest="*_i_p"/>
<copyField source="*_f" dest="*_f_dv"/>
<copyField source="*_f" dest="*_f_p"/>
<copyField source="*_is" dest="*_is_dv"/>
<copyField source="*_s" dest="*_s_dv"/>
<copyField source="*_l" dest="*_l_dv"/>
<copyField source="*_l" dest="*_l_p"/>
<copyField source="*_d" dest="*_d_dv"/>
<copyField source="*_d" dest="*_d_p"/>
<copyField source="*_ss" dest="*_ss_dv"/>
<copyField source="*_is" dest="*_is_dv"/>
<copyField source="*_fs" dest="*_fs_dv"/>

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="example" version="1.6">
<types>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="pint" class="solr.IntPointField"/>
<fieldType name="plong" class="solr.LongPointField"/>
<fieldType name="pdouble" class="solr.DoublePointField"/>
<fieldType name="pfloat" class="solr.FloatPointField"/>
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="float" class="solr.TrieFloatField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="date" class="solr.TrieDateField" sortMissingLast="true" omitNorms="true"/>
</types>
<fields>
<field name="id" type="string"/>
<field name="text" type="string"/>
<field name="_version_" type="long" indexed="true" stored="true" multiValued="false" />
<field name="signatureField" type="string" indexed="true" stored="false"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_sS" type="string" indexed="false" stored="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_p_i" type="pint" indexed="true" stored="true"/>
<dynamicField name="*_p_i_dv" type="pint" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_p_i_mv" type="pint" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_p_i_mv_dv" type="pint" indexed="true" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_i_ni_dv" type="pint" indexed="false" stored="true" docValues="true"/>
<dynamicField name="*_p_i_ni_mv_dv" type="pint" indexed="false" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_l" type="plong" indexed="true" stored="true"/>
<dynamicField name="*_p_l_dv" type="plong" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_p_l_mv" type="plong" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_p_l_mv_dv" type="plong" indexed="true" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_l_ni_dv" type="plong" indexed="false" stored="true" docValues="true"/>
<dynamicField name="*_p_l_ni_mv_dv" type="plong" indexed="false" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_d" type="pdouble" indexed="true" stored="true"/>
<dynamicField name="*_p_d_dv" type="pdouble" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_p_d_mv" type="pdouble" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_p_d_mv_dv" type="pdouble" indexed="true" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_d_ni_dv" type="pdouble" indexed="false" stored="true" docValues="true"/>
<dynamicField name="*_p_d_ni_mv_dv" type="pdouble" indexed="false" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_f" type="pfloat" indexed="true" stored="true"/>
<dynamicField name="*_p_f_dv" type="pfloat" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_p_f_mv" type="pfloat" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_p_f_mv_dv" type="pfloat" indexed="true" stored="true" docValues="true" multiValued="true"/>
<dynamicField name="*_p_f_ni_dv" type="pfloat" indexed="false" stored="true" docValues="true"/>
<dynamicField name="*_p_f_ni_mv_dv" type="pfloat" indexed="false" stored="true" docValues="true" multiValued="true"/>
<!-- return DV fields as -->
<dynamicField name="*_p_i_dv_ns" type="pint" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_l_dv_ns" type="plong" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_d_dv_ns" type="pdouble" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_f_dv_ns" type="pfloat" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
</fields>
<uniqueKey>id</uniqueKey>
</schema>

View File

@ -45,30 +45,30 @@ NOTE: Tests expect every field in this schema to be sortable.
<field name="int" type="int"/>
<field name="int_last" type="int_last"/>
<field name="int_first" type="int_first"/>
<field name="int_dv" type="int_dv"/>
<field name="int_dv_last" type="int_dv_last"/>
<field name="int_dv_first" type="int_dv_first"/>
<field name="int_dv" type="${solr.tests.intClass:pint}_dv"/>
<field name="int_dv_last" type="${solr.tests.intClass:pint}_dv_last"/>
<field name="int_dv_first" type="${solr.tests.intClass:pint}_dv_first"/>
<field name="long" type="long"/>
<field name="long_last" type="long_last"/>
<field name="long_first" type="long_first"/>
<field name="long_dv" type="long_dv"/>
<field name="long_dv_last" type="long_dv_last"/>
<field name="long_dv_first" type="long_dv_first"/>
<field name="long_dv" type="${solr.tests.longClass:plong}_dv"/>
<field name="long_dv_last" type="${solr.tests.longClass:plong}_dv_last"/>
<field name="long_dv_first" type="${solr.tests.longClass:plong}_dv_first"/>
<field name="float" type="float"/>
<field name="float_last" type="float_last"/>
<field name="float_first" type="float_first"/>
<field name="float_dv" type="float_dv"/>
<field name="float_dv_last" type="float_dv_last"/>
<field name="float_dv_first" type="float_dv_first"/>
<field name="float_dv" type="${solr.tests.floatClass:pfloat}_dv"/>
<field name="float_dv_last" type="${solr.tests.floatClass:pfloat}_dv_last"/>
<field name="float_dv_first" type="${solr.tests.floatClass:pfloat}_dv_first"/>
<field name="double" type="double"/>
<field name="double_last" type="double_last"/>
<field name="double_first" type="double_first"/>
<field name="double_dv" type="double_dv"/>
<field name="double_dv_last" type="double_dv_last"/>
<field name="double_dv_first" type="double_dv_first"/>
<field name="double_dv" type="${solr.tests.doubleClass:pdouble}_dv"/>
<field name="double_dv_last" type="${solr.tests.doubleClass:pdouble}_dv_last"/>
<field name="double_dv_first" type="${solr.tests.doubleClass:pdouble}_dv_first"/>
<field name="date" type="date"/>
<field name="date_last" type="date_last"/>
@ -220,6 +220,11 @@ NOTE: Tests expect every field in this schema to be sortable.
sortMissingLast="true"/>
<fieldType name="int_dv_first" class="solr.TrieIntField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="pint_dv" class="solr.IntPointField" stored="true" indexed="false" docValues="true"/>
<fieldType name="pint_dv_last" class="solr.IntPointField" stored="true" indexed="false" docValues="true"
sortMissingLast="true"/>
<fieldType name="pint_dv_first" class="solr.IntPointField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="long" class="solr.TrieLongField" stored="true" indexed="true"/>
<fieldType name="long_last" class="solr.TrieLongField" stored="true" indexed="true" sortMissingLast="true"/>
@ -229,6 +234,11 @@ NOTE: Tests expect every field in this schema to be sortable.
sortMissingLast="true"/>
<fieldType name="long_dv_first" class="solr.TrieLongField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="plong_dv" class="solr.LongPointField" stored="true" indexed="false" docValues="true"/>
<fieldType name="plong_dv_last" class="solr.LongPointField" stored="true" indexed="false" docValues="true"
sortMissingLast="true"/>
<fieldType name="plong_dv_first" class="solr.LongPointField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="float" class="solr.TrieFloatField" stored="true" indexed="true"/>
<fieldType name="float_last" class="solr.TrieFloatField" stored="true" indexed="true" sortMissingLast="true"/>
@ -238,6 +248,11 @@ NOTE: Tests expect every field in this schema to be sortable.
sortMissingLast="true"/>
<fieldType name="float_dv_first" class="solr.TrieFloatField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="pfloat_dv" class="solr.FloatPointField" stored="true" indexed="false" docValues="true"/>
<fieldType name="pfloat_dv_last" class="solr.FloatPointField" stored="true" indexed="false" docValues="true"
sortMissingLast="true"/>
<fieldType name="pfloat_dv_first" class="solr.FloatPointField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="double" class="solr.TrieDoubleField" stored="true" indexed="true"/>
<fieldType name="double_last" class="solr.TrieDoubleField" stored="true" indexed="true" sortMissingLast="true"/>
@ -247,6 +262,11 @@ NOTE: Tests expect every field in this schema to be sortable.
sortMissingLast="true"/>
<fieldType name="double_dv_first" class="solr.TrieDoubleField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="pdouble_dv" class="solr.DoublePointField" stored="true" indexed="false" docValues="true"/>
<fieldType name="pdouble_dv_last" class="solr.DoublePointField" stored="true" indexed="false" docValues="true"
sortMissingLast="true"/>
<fieldType name="pdouble_dv_first" class="solr.DoublePointField" stored="true" indexed="false" docValues="true"
sortMissingFirst="true"/>
<fieldType name="date" class="solr.TrieDateField" stored="true" indexed="true"/>
<fieldType name="date_last" class="solr.TrieDateField" stored="true" indexed="true" sortMissingLast="true"/>

View File

@ -43,6 +43,12 @@
<fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<!-- Point Fields -->
<fieldType name="pint" class="solr.IntPointField" docValues="true"/>
<fieldType name="plong" class="solr.LongPointField" docValues="true"/>
<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
<fieldType name="pfloat" class="solr.FloatPointField" docValues="true"/>
<!-- Field type demonstrating an Analyzer failure -->
<fieldType name="failtype1" class="solr.TextField">
@ -550,7 +556,7 @@
<field name="dateRange" type="dateRange" multiValued="true"/>
<field name="cat" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="price" type="float" indexed="true" stored="true" multiValued="false"/>
<field name="price" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true" multiValued="false"/>
<field name="inStock" type="boolean" indexed="true" stored="true"/>
<field name="subword" type="subword" indexed="true" stored="true"/>
@ -599,7 +605,7 @@
-->
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_i1" type="int" indexed="true" stored="true" multiValued="false" sortMissingLast="true"/>
<dynamicField name="*_idv" type="int" indexed="true" stored="true" docValues="true" multiValued="false"/>
<dynamicField name="*_idv" type="${solr.tests.intClass:pint}" indexed="true" stored="true" docValues="true" multiValued="false"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
@ -610,9 +616,9 @@
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
<dynamicField name="*_b1" type="boolean" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_f1" type="float" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_f1" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_d1" type="double" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_d1" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_dt1" type="date" indexed="true" stored="true" multiValued="false"/>
@ -662,7 +668,7 @@
<dynamicField name="*_mfacet" type="string" indexed="true" stored="false" multiValued="true"/>
<!-- Type used to index the lat and lon components for the "location" FieldType -->
<dynamicField name="*_coordinate" type="tdouble" indexed="true" stored="false" omitNorms="true"/>
<dynamicField name="*_coordinate" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="false" omitNorms="true"/>
<dynamicField name="*_path" type="path" indexed="true" stored="true" omitNorms="true" multiValued="true"/>
<dynamicField name="*_ancestor" type="ancestor_path" indexed="true" stored="true" omitNorms="true"
@ -676,12 +682,12 @@
<dynamicField name="*_f_dv" type="float" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_d_dv" type="double" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_dt_dv" type="date" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_f1_dv" type="float" indexed="true" stored="true" docValues="true" multiValued="false"/>
<dynamicField name="*_f1_dv" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true" docValues="true" multiValued="false"/>
<!-- Non-stored, DocValues=true -->
<dynamicField name="*_i_dvo" multiValued="false" type="int" docValues="true" indexed="true" stored="false"
<dynamicField name="*_i_dvo" multiValued="false" type="${solr.tests.intClass:pint}" docValues="true" indexed="true" stored="false"
useDocValuesAsStored="true"/>
<dynamicField name="*_d_dvo" multiValued="false" type="double" docValues="true" indexed="true" stored="false"
<dynamicField name="*_d_dvo" multiValued="false" type="${solr.tests.doubleClass:pdouble}" docValues="true" indexed="true" stored="false"
useDocValuesAsStored="true"/>
<dynamicField name="*_s_dvo" multiValued="false" type="string" docValues="true" indexed="true" stored="false"
useDocValuesAsStored="true"/>
@ -691,8 +697,8 @@
useDocValuesAsStored="true"/>
<!-- Non-stored, DocValues=true, useDocValuesAsStored=false -->
<field name="single_i_dvn" multiValued="false" type="int" indexed="true" stored="true"/>
<field name="single_d_dvn" multiValued="false" type="double" indexed="true" stored="true"/>
<field name="single_i_dvn" multiValued="false" type="${solr.tests.intClass:pint}" indexed="true" stored="true"/>
<field name="single_d_dvn" multiValued="false" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="true"/>
<field name="single_s_dvn" multiValued="false" type="string" indexed="true" stored="true"/>
<field name="copy_single_i_dvn" multiValued="false" type="int" docValues="true" indexed="true" stored="false"
useDocValuesAsStored="false"/>

View File

@ -77,7 +77,12 @@
<fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>
<!-- Point Fields -->
<fieldType name="pint" class="solr.IntPointField" docValues="true"/>
<fieldType name="plong" class="solr.LongPointField" docValues="true"/>
<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
<fieldType name="pfloat" class="solr.FloatPointField" docValues="true"/>
<!-- The format for this date field is of the form 1995-12-31T23:59:59Z, and
is a more restricted form of the canonical representation of dateTime
@ -340,15 +345,15 @@ valued. -->
<dynamicField name="*_s_dv" type="string" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ss" type="string" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_sS" type="string" indexed="false" stored="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_i" type="${solr.tests.intClass:pint}" indexed="true" stored="true"/>
<dynamicField name="*_ii" type="int" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_l" type="${solr.tests.longClass:plong}" indexed="true" stored="true"/>
<dynamicField name="*_f" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true"/>
<dynamicField name="*_d" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="true"/>
<dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>
<dynamicField name="*_ti_dv" type="int" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ti_ni_dv" type="int" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ti_dv" type="tint" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ti_ni_dv" type="tint" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/>
<dynamicField name="*_tl_dv" type="tlong" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_tl_ni_dv" type="tlong" indexed="false" stored="true" docValues="true"/>

View File

@ -42,6 +42,12 @@
<fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<!-- Point Fields -->
<fieldType name="pint" class="solr.IntPointField" docValues="true"/>
<fieldType name="plong" class="solr.LongPointField" docValues="true"/>
<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
<fieldType name="pfloat" class="solr.FloatPointField" docValues="true"/>
<!-- Field type demonstrating an Analyzer failure -->
<fieldType name="failtype1" class="solr.TextField">
@ -432,7 +438,7 @@
<field name="text" type="text" indexed="true" stored="false"/>
<field name="subject" type="text" indexed="true" stored="true"/>
<field name="title" type="nametext" indexed="true" stored="true"/>
<field name="weight" type="float" indexed="true" stored="true"/>
<field name="weight" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true"/>
<field name="bday" type="date" indexed="true" stored="true"/>
<field name="text_np" type="text_np" indexed="true" stored="false"/>
@ -550,7 +556,8 @@
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_is" type="int" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_idv" type="int" indexed="true" stored="true" docValues="true" multiValued="false"/>
<dynamicField name="*_i_dv" type="${solr.tests.intClass:pint}" indexed="true" stored="true" docValues="true" multiValued="false"/>
<dynamicField name="*_is_dv" type="${solr.tests.intClass:pint}" indexed="true" stored="true" docValues="true" multiValued="false"/>
<dynamicField name="*_s1" type="string" indexed="true" stored="true" multiValued="false"/>
<!-- :TODO: why are these identical?!?!?! -->
<dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true"/>
@ -559,9 +566,11 @@
<dynamicField name="*_t" type="text" indexed="true" stored="true"/>
<dynamicField name="*_tt" type="text" indexed="true" stored="true"/>
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_f" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_pi" type="pint" indexed="true" stored="true" docValues="false" multiValued="false"/>
<!-- some trie-coded dynamic fields for faster range queries -->
<dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>

View File

@ -202,7 +202,7 @@
<!-- docvalues and stored are exclusive -->
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_is" type="int" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_id" type="int" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_id" type="${solr.tests.intClass:pint}" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_ids" type="int" indexed="true" stored="false" multiValued="true" docValues="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_s1" type="string" indexed="true" stored="true"/>
@ -215,11 +215,11 @@
<dynamicField name="*_lds" type="long" indexed="true" stored="false" multiValued="true" docValues="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_fs" type="float" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_fd" type="float" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_fd" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_fds" type="float" indexed="true" stored="false" multiValued="true" docValues="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_ds" type="double" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_dd" type="double" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_dd" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_dds" type="double" indexed="true" stored="false" multiValued="true" docValues="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_dts" type="date" indexed="true" stored="true" multiValued="true"/>
@ -227,15 +227,15 @@
<dynamicField name="*_dtds" type="date" indexed="true" stored="false" multiValued="true" docValues="true"/>
<!-- docvalues and stored (S suffix) -->
<dynamicField name="*_idS" type="int" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_idS" type="${solr.tests.intClass:pint}" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_idsS" type="int" indexed="true" stored="true" multiValued="true" docValues="true"/>
<dynamicField name="*_sdS" type="string" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_sdsS" type="string" indexed="true" stored="true" multiValued="true" docValues="true"/>
<dynamicField name="*_ldS" type="long" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ldS" type="${solr.tests.longClass:plong}" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ldsS" type="long" indexed="true" stored="true" multiValued="true" docValues="true"/>
<dynamicField name="*_fdS" type="float" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_fdS" type="${solr.tests.floatClass:pfloat}" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_fdsS" type="float" indexed="true" stored="true" multiValued="true" docValues="true"/>
<dynamicField name="*_ddS" type="double" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ddS" type="${solr.tests.doubleClass:pdouble}" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_ddsS" type="double" indexed="true" stored="true" multiValued="true" docValues="true"/>
<dynamicField name="*_dtdS" type="date" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_dtdsS" type="date" indexed="true" stored="true" multiValued="true" docValues="true"/>
@ -394,6 +394,13 @@
<fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" positionIncrementGap="0"/>
<fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" positionIncrementGap="0"/>
<fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" positionIncrementGap="0"/>
<!-- Point Fields -->
<fieldType name="pint" class="solr.IntPointField"/>
<fieldType name="plong" class="solr.LongPointField"/>
<fieldType name="pdouble" class="solr.DoublePointField"/>
<fieldType name="pfloat" class="solr.FloatPointField"/>
<!-- The format for this date field is of the form 1995-12-31T23:59:59Z, and
is a more restricted form of the canonical representation of dateTime

View File

@ -16,19 +16,20 @@
*/
package org.apache.solr;
import java.io.IOException;
import java.util.List;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.SolrDocumentList;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
/**
* TODO? perhaps use:
* http://docs.codehaus.org/display/JETTY/ServletTester
@ -37,6 +38,7 @@ import java.util.List;
* @since solr 4.0
*/
@Slow
@SuppressPointFields
public class TestDistributedGrouping extends BaseDistributedSearchTestCase {
String t1="a_t";

View File

@ -16,6 +16,7 @@
*/
package org.apache.solr;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.noggit.JSONUtil;
import org.noggit.ObjectBuilder;
@ -36,6 +37,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
@SuppressPointFields
public class TestJoin extends SolrTestCaseJ4 {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ -151,7 +153,7 @@ public class TestJoin extends SolrTestCaseJ4 {
// increase test effectiveness by avoiding 0 resultsets much of the time.
String[][] compat = new String[][] {
{"small_s","small2_s","small2_ss","small3_ss"},
{"small_i","small2_i","small2_is","small3_is"}
{"small_i","small2_i","small2_is","small3_is", "small_i_dv", "small_is_dv"}
};
@ -169,6 +171,8 @@ public class TestJoin extends SolrTestCaseJ4 {
types.add(new FldType("small2_i",ZERO_ONE, new IRange(0,5+indexSize/3)));
types.add(new FldType("small2_is",ZERO_TWO, new IRange(0,5+indexSize/3)));
types.add(new FldType("small3_is",new IRange(0,25), new IRange(0,100)));
types.add(new FldType("small_i_dv",ZERO_ONE, new IRange(0,5+indexSize/3)));
types.add(new FldType("small_is_dv",ZERO_ONE, new IRange(0,5+indexSize/3)));
clearIndex();
Map<Comparable, Doc> model = indexDocs(types, null, indexSize);

View File

@ -62,7 +62,9 @@ public class TestRandomDVFaceting extends SolrTestCaseJ4 {
types = new ArrayList<>();
types.add(new FldType("id",ONE_ONE, new SVal('A','Z',4,4)));
types.add(new FldType("score_f",ONE_ONE, new FVal(1,100)));
types.add(new FldType("score_d",ONE_ONE, new FVal(1,100)));
types.add(new FldType("foo_i",ZERO_ONE, new IRange(0,indexSize)));
types.add(new FldType("foo_l",ZERO_ONE, new IRange(0,indexSize)));
types.add(new FldType("small_s",ZERO_ONE, new SVal('a',(char)('c'+indexSize/3),1,1)));
types.add(new FldType("small2_s",ZERO_ONE, new SVal('a',(char)('c'+indexSize/3),1,1)));
types.add(new FldType("small2_ss",ZERO_TWO, new SVal('a',(char)('c'+indexSize/3),1,1)));
@ -231,6 +233,12 @@ public class TestRandomDVFaceting extends SolrTestCaseJ4 {
responses.add(strResponse);
}
// If there is a PointField option for this test, also test it
if (h.getCore().getLatestSchema().getFieldOrNull(facet_field + "_p") != null) {
params.set("facet.field", "{!key="+facet_field+"}"+facet_field+"_p");
String strResponse = h.query(req(params));
responses.add(strResponse);
}
/**
String strResponse = h.query(req(params));

View File

@ -184,7 +184,6 @@ public class TestRandomFaceting extends SolrTestCaseJ4 {
SolrQueryRequest req = req();
try {
Random rand = random();
boolean validate = validateResponses;
ModifiableSolrParams params = params("facet","true", "wt","json", "indent","true", "omitHeader","true");
params.add("q","*:*"); // TODO: select subsets
params.add("rows","0");
@ -244,8 +243,9 @@ public class TestRandomFaceting extends SolrTestCaseJ4 {
List<String> methods = multiValued ? multiValuedMethods : singleValuedMethods;
List<String> responses = new ArrayList<>(methods.size());
for (String method : methods) {
for (boolean exists : new boolean [] {false, true}) {
for (boolean exists : new boolean[]{false, true}) {
// params.add("facet.field", "{!key="+method+"}" + ftype.fname);
// TODO: allow method to be passed on local params?
if (method!=null) {
@ -253,7 +253,6 @@ public class TestRandomFaceting extends SolrTestCaseJ4 {
} else {
params.remove("facet.method");
}
params.set("facet.exists", ""+exists);
if (!exists && rand.nextBoolean()) {
params.remove("facet.exists");
@ -275,6 +274,13 @@ public class TestRandomFaceting extends SolrTestCaseJ4 {
"facet.exists", req(params), ErrorCode.BAD_REQUEST);
continue;
}
if (exists && sf.getType().isPointField()) {
// PointFields don't yet support "enum" method or the "facet.exists" parameter
assertQEx("Expecting failure, since ",
"facet.exists=true is requested, but facet.method=enum can't be used with " + sf.getName(),
req(params), ErrorCode.BAD_REQUEST);
continue;
}
}
String strResponse = h.query(req(params));
responses.add(strResponse);

View File

@ -29,6 +29,7 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.FieldStatsInfo;
import org.apache.solr.client.solrj.response.PivotField;
@ -78,6 +79,7 @@ import static org.apache.solr.common.params.FacetParams.FACET_DISTRIB_MCO;
*
*/
@SuppressSSL // Too Slow
@SuppressPointFields
public class TestCloudPivotFacet extends AbstractFullDistribZkTestBase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

View File

@ -40,7 +40,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
public class XsltUpdateRequestHandlerTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeTests() throws Exception {
initCore("solrconfig.xml","schema.xml");

View File

@ -16,19 +16,19 @@
*/
package org.apache.solr.handler.admin;
import java.util.Arrays;
import java.util.EnumSet;
import org.apache.solr.common.luke.FieldFlag;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.CustomAnalyzerStrField; // jdoc
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.util.TestHarness;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Arrays;
import java.util.EnumSet;
/**
* :TODO: currently only tests some of the utilities in the LukeRequestHandler
*/

View File

@ -16,15 +16,19 @@
*/
package org.apache.solr.handler.component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.search.CollapsingQParserPlugin;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.*;
@SuppressPointFields
public class TestExpandComponent extends SolrTestCaseJ4 {
@BeforeClass

View File

@ -17,7 +17,9 @@
package org.apache.solr.request;
import org.apache.solr.request.SimpleFacets.FacetMethod;
import org.apache.solr.schema.BoolField;
import org.apache.solr.schema.IntPointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.StrField;
import org.apache.solr.schema.TrieIntField;
@ -203,5 +205,15 @@ public class TestFacetMethods {
assertEquals(SimpleFacets.FacetMethod.ENUM, SimpleFacets.selectFacetMethod(field, null, 1));
}
@Test
public void testPointFields() {
// Methods other than FCS are not currently supported for PointFields
SchemaField field = new SchemaField("foo", new IntPointField());
assertEquals(SimpleFacets.FacetMethod.FCS, SimpleFacets.selectFacetMethod(field, null, 0));
assertEquals(SimpleFacets.FacetMethod.FCS, SimpleFacets.selectFacetMethod(field, FacetMethod.ENUM, 0));
assertEquals(SimpleFacets.FacetMethod.FCS, SimpleFacets.selectFacetMethod(field, FacetMethod.FC, 0));
assertEquals(SimpleFacets.FacetMethod.FCS, SimpleFacets.selectFacetMethod(field, FacetMethod.FCS, 0));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,7 @@ import java.util.Iterator;
import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
@ -36,8 +37,9 @@ import org.junit.Test;
//We want codecs that support DocValues, and ones supporting blank/empty values.
@SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42"})
@SuppressPointFields
public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-collapseqparser.xml", "schema11.xml");

View File

@ -46,7 +46,7 @@ public class TestMaxScoreQueryParser extends AbstractSolrTestCase {
assertEquals(new BoostQuery(new TermQuery(new Term("text", "foo")), 3f), q);
q = parse("price:[0 TO 10]");
assertTrue(q instanceof LegacyNumericRangeQuery);
assertTrue(q instanceof LegacyNumericRangeQuery || q instanceof PointRangeQuery);
}
@Test

View File

@ -24,6 +24,7 @@ import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.CursorPagingTest;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
@ -38,6 +39,7 @@ import org.junit.BeforeClass;
//We want codecs that support DocValues, and ones supporting blank/empty values.
@SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42"})
@SuppressPointFields
public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
/** Full SolrServer instance for arbitrary introspection of response data and adding fqs */

View File

@ -23,6 +23,7 @@ import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.search.TermQuery;
@ -231,6 +232,13 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
qParser.setIsFilter(true); // this may change in the future
q = qParser.getQuery();
assertEquals(20, ((TermInSetQuery)q).getTermData().size());
// for point fields large filter query should use PointInSetQuery
qParser = QParser.getParser("foo_pi:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
qParser.setIsFilter(true); // this may change in the future
q = qParser.getQuery();
assertTrue(q instanceof PointInSetQuery);
assertEquals(20, ((PointInSetQuery)q).getPackedPoints().size());
// a filter() clause inside a relevancy query should be able to use a TermsQuery
qParser = QParser.getParser("foo_s:aaa filter(foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z))", req);

View File

@ -34,6 +34,7 @@ import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.JSONTestUtil;
import org.apache.solr.SolrTestCaseHS;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.request.macro.MacroExpander;
import org.junit.AfterClass;
@ -41,6 +42,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
@LuceneTestCase.SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Lucene45","Appending"})
@SuppressPointFields
public class TestJsonFacets extends SolrTestCaseHS {
private static SolrInstances servers; // for distributed testing

View File

@ -167,11 +167,18 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
public static final String SYSTEM_PROPERTY_SOLR_TESTS_USEMERGEPOLICYFACTORY = "solr.tests.useMergePolicyFactory";
@Deprecated // remove solr.tests.useMergePolicy use with SOLR-8668
public static final String SYSTEM_PROPERTY_SOLR_TESTS_USEMERGEPOLICY = "solr.tests.useMergePolicy";
/**
* The system property {@code "solr.tests.preferPointFields"} can be used to make tests use PointFields when possible.
* PointFields will only be used if the schema used by the tests uses "${solr.tests.TYPEClass}" when defining fields.
* If this environment variable is not set, those tests will use PointFields 50% of the times and TrieFields the rest.
*/
public static final boolean PREFER_POINT_FIELDS = Boolean.getBoolean("solr.tests.preferPointFields");
private static String coreName = DEFAULT_TEST_CORENAME;
public static int DEFAULT_CONNECTION_TIMEOUT = 60000; // default socket connection timeout in ms
protected void writeCoreProperties(Path coreDirectory, String corename) throws IOException {
Properties props = new Properties();
props.setProperty("name", corename);
@ -215,6 +222,19 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
public String bugUrl();
}
/**
* Annotation for test classes that want to disable PointFields.
* PointFields will otherwise randomly used by some schemas.
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SuppressPointFields {
/** Point to JIRA entry. */
public String bugUrl() default "None";
}
// these are meant to be accessed sequentially, but are volatile just to ensure any test
// thread will read the latest value
protected static volatile SSLTestConfig sslConfig;
@ -419,10 +439,12 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
lrf = h.getRequestFactory("standard", 0, 20, CommonParams.VERSION, "2.2");
}
/** sets system properties based on
/**
* Sets system properties to allow generation of random configurations of
* solrconfig.xml and schema.xml.
* Sets properties used on
* {@link #newIndexWriterConfig(org.apache.lucene.analysis.Analyzer)}
*
* configs can use these system properties to vary the indexwriter settings
* and base schema.xml (Point Fields)
*/
public static void newRandomConfig() {
IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random()));
@ -438,6 +460,20 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
mergeSchedulerClass = "org.apache.lucene.index.ConcurrentMergeScheduler";
}
System.setProperty("solr.tests.mergeScheduler", mergeSchedulerClass);
if (RandomizedContext.current().getTargetClass().isAnnotationPresent(SuppressPointFields.class)
|| (!PREFER_POINT_FIELDS && random().nextBoolean())) {
log.info("Using TrieFields");
System.setProperty("solr.tests.intClass", "int");
System.setProperty("solr.tests.longClass", "long");
System.setProperty("solr.tests.doubleClass", "double");
System.setProperty("solr.tests.floatClass", "float");
} else {
log.info("Using PointFields");
System.setProperty("solr.tests.intClass", "pint");
System.setProperty("solr.tests.longClass", "plong");
System.setProperty("solr.tests.doubleClass", "pdouble");
System.setProperty("solr.tests.floatClass", "pfloat");
}
}
public static Throwable getWrappedException(Throwable e) {