org.apache.solr.schema.PointType Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of solr-core Show documentation
Show all versions of solr-core Show documentation
Apache Solr (module: core)
/*
* 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.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.VectorValueSource;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.response.TextResponseWriter;
import org.apache.solr.search.QParser;
import org.apache.solr.search.SpatialOptions;
import org.apache.solr.uninverting.UninvertingReader.Type;
import org.locationtech.spatial4j.distance.DistanceUtils;
/**
* A point type that indexes a point in an n-dimensional space as separate fields and supports range queries.
* See {@link LatLonType} for geo-spatial queries.
*/
public class PointType extends CoordinateFieldType implements SpatialQueryable {
@Override
protected void init(IndexSchema schema, Map args) {
SolrParams p = new MapSolrParams(args);
dimension = p.getInt(DIMENSION, DEFAULT_DIMENSION);
if (dimension < 1) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
"The dimension must be > 0: " + dimension);
}
args.remove(DIMENSION);
super.init(schema, args);
// cache suffixes
createSuffixCache(dimension);
}
@Override
public boolean isPolyField() {
return true; // really only true if the field is indexed
}
@Override
public List createFields(SchemaField field, Object value) {
String externalVal = value.toString();
String[] point = parseCommaSeparatedList(externalVal, dimension);
// TODO: this doesn't currently support polyFields as sub-field types
List f = new ArrayList<>((dimension*2)+1);
if (field.indexed()) {
for (int i=0; i vs = new ArrayList<>(dimension);
for (int i=0; idimension values encoded in it, separated by commas,
* return a String array of length dimension containing the values.
*
* @param externalVal The value to parse
* @param dimension The expected number of values for the point
* @return An array of the values that make up the point (aka vector)
* @throws SolrException if the dimension specified does not match the number found
*/
public static String[] parseCommaSeparatedList(String externalVal, int dimension) throws SolrException {
//TODO: Should we support sparse vectors?
String[] out = new String[dimension];
int idx = externalVal.indexOf(',');
int end = idx;
int start = 0;
int i = 0;
if (idx == -1 && dimension == 1 && externalVal.length() > 0) {//we have a single point, dimension better be 1
out[0] = externalVal.trim();
i = 1;
} else if (idx > 0) {//if it is zero, that is an error
//Parse out a comma separated list of values, as in: 73.5,89.2,7773.4
for (; i < dimension; i++) {
while (start < end && externalVal.charAt(start) == ' ') start++;
while (end > start && externalVal.charAt(end - 1) == ' ') end--;
if (start == end) {
break;
}
out[i] = externalVal.substring(start, end);
start = idx + 1;
end = externalVal.indexOf(',', start);
idx = end;
if (end == -1) {
end = externalVal.length();
}
}
}
if (i != dimension) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"incompatible dimension (" + dimension +
") and values (" + externalVal + "). Only " + i + " values specified");
}
return out;
}
@Override
public double getSphereRadius() {
// This won't likely be used. You should probably be using LatLonType instead if you felt the need for this.
// This is here just for backward compatibility reasons.
return DistanceUtils.EARTH_MEAN_RADIUS_KM;
}
}
class PointTypeValueSource extends VectorValueSource {
private final SchemaField sf;
public PointTypeValueSource(SchemaField sf, List sources) {
super(sources);
this.sf = sf;
}
@Override
public String name() {
return "point";
}
@Override
public String description() {
return name()+"("+sf.getName()+")";
}
}