All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.schema.PointType Maven / Gradle / Ivy

There is a newer version: 9.6.1
Show newest version
/*
 * 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 org.apache.lucene.document.FieldType;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.VectorValueSource;
import org.apache.lucene.index.IndexableField;
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 java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

/**
 * 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, float boost) {
    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+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;
  }

}


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()+")";
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy