Skip to content

Commit

Permalink
Use generics for doc value object types (#745)
Browse files Browse the repository at this point in the history
  • Loading branch information
aprudhomme authored Oct 3, 2024
1 parent 70156a1 commit 1155762
Show file tree
Hide file tree
Showing 20 changed files with 443 additions and 414 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
import org.apache.lucene.search.Query;

/** Field class for 'BOOLEAN' field type. */
public class BooleanFieldDef extends IndexableFieldDef implements TermQueryable {
public class BooleanFieldDef extends IndexableFieldDef<Boolean> implements TermQueryable {
protected BooleanFieldDef(String name, Field requestField) {
super(name, requestField);
super(name, requestField, Boolean.class);
}

@Override
Expand Down Expand Up @@ -113,7 +113,7 @@ public void parseDocumentField(
}

@Override
public LoadedDocValues<?> getDocValues(LeafReaderContext context) throws IOException {
public LoadedDocValues<Boolean> getDocValues(LeafReaderContext context) throws IOException {
if (docValuesType == DocValuesType.NUMERIC) {
NumericDocValues numericDocValues = DocValues.getNumeric(context.reader(), getName());
return new LoadedDocValues.SingleBoolean(numericDocValues);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.apache.lucene.search.suggest.document.Completion912PostingsFormat;
import org.apache.lucene.search.suggest.document.ContextSuggestField;

public class ContextSuggestFieldDef extends IndexableFieldDef {
public class ContextSuggestFieldDef extends IndexableFieldDef<Void> {
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
private final Analyzer indexAnalyzer;
private final Analyzer searchAnalyzer;
Expand All @@ -38,7 +38,7 @@ public class ContextSuggestFieldDef extends IndexableFieldDef {
* @param requestField field definition from grpc request
*/
protected ContextSuggestFieldDef(String name, Field requestField) {
super(name, requestField);
super(name, requestField, Void.class);
this.indexAnalyzer = this.parseIndexAnalyzer(requestField);
this.searchAnalyzer = this.parseSearchAnalyzer(requestField);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
import org.apache.lucene.search.SortField;

/** Field class for 'DATE_TIME' field type. */
public class DateTimeFieldDef extends IndexableFieldDef implements Sortable, RangeQueryable {
public class DateTimeFieldDef extends IndexableFieldDef<Instant>
implements Sortable, RangeQueryable {
private static final String EPOCH_MILLIS = "epoch_millis";
private static final String STRICT_DATE_OPTIONAL_TIME = "strict_date_optional_time";

Expand Down Expand Up @@ -79,7 +80,7 @@ private static DateTimeFormatter createDateTimeFormatter(String dateTimeFormat)
}

public DateTimeFieldDef(String name, Field requestField) {
super(name, requestField);
super(name, requestField, Instant.class);
dateTimeFormat = requestField.getDateTimeFormat();
dateTimeFormatter = createDateTimeFormatter(dateTimeFormat);
}
Expand Down Expand Up @@ -278,7 +279,7 @@ private long getTimeFromEpochMillisString(String epochMillisString) {
}

@Override
public LoadedDocValues<?> getDocValues(LeafReaderContext context) throws IOException {
public LoadedDocValues<Instant> getDocValues(LeafReaderContext context) throws IOException {
if (docValuesType == DocValuesType.NUMERIC) {
NumericDocValues numericDocValues = DocValues.getNumeric(context.reader(), getName());
return new LoadedDocValues.SingleDateTime(numericDocValues);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
import org.apache.lucene.util.NumericUtils;

/** Field class for 'DOUBLE' field type. */
public class DoubleFieldDef extends NumberFieldDef {
public class DoubleFieldDef extends NumberFieldDef<Double> {

public DoubleFieldDef(String name, Field requestField) {
super(name, requestField, DOUBLE_PARSER);
super(name, requestField, DOUBLE_PARSER, Double.class);
}

@Override
Expand All @@ -59,12 +59,12 @@ protected org.apache.lucene.document.Field getPointField(Number fieldValue) {
}

@Override
protected LoadedDocValues<?> getNumericDocValues(NumericDocValues docValues) {
protected LoadedDocValues<Double> getNumericDocValues(NumericDocValues docValues) {
return new LoadedDocValues.SingleDouble(docValues);
}

@Override
protected LoadedDocValues<?> getSortedNumericDocValues(SortedNumericDocValues docValues) {
protected LoadedDocValues<Double> getSortedNumericDocValues(SortedNumericDocValues docValues) {
return new LoadedDocValues.SortedDoubles(docValues);
}

Expand Down Expand Up @@ -160,7 +160,7 @@ public Query getTermQueryFromTextValue(String textValue) {

@Override
public Query getTermInSetQueryFromTextValues(List<String> textValues) {
List<Double> doubleTerms = new ArrayList(textValues.size());
List<Double> doubleTerms = new ArrayList<>(textValues.size());
textValues.forEach((s) -> doubleTerms.add(Double.parseDouble(s)));
return DoublePoint.newSetQuery(getName(), doubleTerms);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public FieldDefCreator(LuceneServerConfiguration configuration) {
(name, field) -> {
throw new UnsupportedOperationException("Runtime fields should be created directly");
});
register("VECTOR", VectorFieldDef::new);
register("VECTOR", VectorFieldDef::createField);
register("CONTEXT_SUGGEST", ContextSuggestFieldDef::new);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
import org.apache.lucene.util.NumericUtils;

/** Field class for 'FLOAT' field type. */
public class FloatFieldDef extends NumberFieldDef {
public class FloatFieldDef extends NumberFieldDef<Float> {

public FloatFieldDef(String name, Field requestField) {
super(name, requestField, FLOAT_PARSER);
super(name, requestField, FLOAT_PARSER, Float.class);
}

@Override
Expand All @@ -59,12 +59,12 @@ protected org.apache.lucene.document.Field getPointField(Number fieldValue) {
}

@Override
protected LoadedDocValues<?> getNumericDocValues(NumericDocValues docValues) {
protected LoadedDocValues<Float> getNumericDocValues(NumericDocValues docValues) {
return new LoadedDocValues.SingleFloat(docValues);
}

@Override
protected LoadedDocValues<?> getSortedNumericDocValues(SortedNumericDocValues docValues) {
protected LoadedDocValues<Float> getSortedNumericDocValues(SortedNumericDocValues docValues) {
return new LoadedDocValues.SortedFloats(docValues);
}

Expand Down Expand Up @@ -159,7 +159,7 @@ public Query getTermQueryFromTextValue(String textValue) {

@Override
public Query getTermInSetQueryFromTextValues(List<String> textValues) {
List<Float> floatTerms = new ArrayList(textValues.size());
List<Float> floatTerms = new ArrayList<>(textValues.size());
textValues.forEach((s) -> floatTerms.add(Float.parseFloat(s)));
return FloatPoint.newSetQuery(getName(), floatTerms);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
import org.apache.lucene.util.BytesRef;

/** Field class for defining '_ID' fields which are used to update documents */
public class IdFieldDef extends IndexableFieldDef implements TermQueryable {
public class IdFieldDef extends IndexableFieldDef<String> implements TermQueryable {

protected IdFieldDef(String name, Field requestField) {
super(name, requestField);
super(name, requestField, String.class);
}

/**
Expand Down Expand Up @@ -119,7 +119,7 @@ public DocValuesType parseDocValuesType(Field requestField) {
* @throws IOException
*/
@Override
public LoadedDocValues<?> getDocValues(LeafReaderContext context) throws IOException {
public LoadedDocValues<String> getDocValues(LeafReaderContext context) throws IOException {
if (hasDocValues()) {
SortedDocValues sortedDocValues = DocValues.getSorted(context.reader(), getName());
return new LoadedDocValues.SingleString(sortedDocValues);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.similarities.Similarity;

/** Base class for all field definition types that can be written into the index. */
public abstract class IndexableFieldDef extends FieldDef {
/**
* Base class for all field definition types that can be written into the index.
*
* @param <T> doc value object type
*/
public abstract class IndexableFieldDef<T> extends FieldDef {
public enum FacetValueType {
NO_FACETS,
FLAT,
Expand All @@ -52,8 +56,9 @@ public enum FacetValueType {
private final PostingsFormat postingsFormat;
private final DocValuesFormat docValuesFormat;
private final Similarity similarity;
private final Class<? super T> docValuesObjectClass;

private final Map<String, IndexableFieldDef> childFields;
private final Map<String, IndexableFieldDef<?>> childFields;

protected final DocValuesType docValuesType;
protected final IndexableFieldDef.FacetValueType facetValueType;
Expand All @@ -68,8 +73,10 @@ public enum FacetValueType {
*
* @param name name of field
* @param requestField field definition from grpc request
* @param docValuesObjectClass class of doc values object
*/
protected IndexableFieldDef(String name, Field requestField) {
protected IndexableFieldDef(
String name, Field requestField, Class<? super T> docValuesObjectClass) {
super(name);

validateRequest(requestField);
Expand Down Expand Up @@ -101,17 +108,19 @@ protected IndexableFieldDef(String name, Field requestField) {
this.similarity =
SimilarityCreator.getInstance().createSimilarity(similarityStr, similarityParams);

this.docValuesObjectClass = docValuesObjectClass;

// add any children this field has
if (requestField.getChildFieldsCount() > 0) {
Map<String, IndexableFieldDef> childFields = new HashMap<>();
Map<String, IndexableFieldDef<?>> childFields = new HashMap<>();
for (Field field : requestField.getChildFieldsList()) {
checkChildName(field.getName());
String childName = getName() + IndexState.CHILD_FIELD_SEPARATOR + field.getName();
FieldDef fieldDef = FieldDefCreator.getInstance().createFieldDef(childName, field);
if (!(fieldDef instanceof IndexableFieldDef)) {
throw new IllegalArgumentException("Child field is not indexable: " + childName);
}
childFields.put(childName, (IndexableFieldDef) fieldDef);
childFields.put(childName, (IndexableFieldDef<?>) fieldDef);
}
this.childFields = Collections.unmodifiableMap(childFields);
} else {
Expand All @@ -132,19 +141,19 @@ private void checkChildName(String name) {
}

/**
* Method called by {@link #IndexableFieldDef(String, Field)} to validate the provided {@link
* Field}. Field definitions should define a version that checks for incompatible parameters and
* any other potential issues. It is recommended to also call the super version of this method, so
* that general checks do not need to be repeated everywhere.
* Method called by {@link #IndexableFieldDef(String, Field, Class)} to validate the provided
* {@link Field}. Field definitions should define a version that checks for incompatible
* parameters and any other potential issues. It is recommended to also call the super version of
* this method, so that general checks do not need to be repeated everywhere.
*
* @param requestField field properties to validate
*/
protected void validateRequest(Field requestField) {}

/**
* Method called by {@link #IndexableFieldDef(String, Field)} to determine the doc value type used
* by this field. Fields are not necessarily limited to one doc value, but this should represent
* the primary value that will be accessible to scripts and search through {@link
* Method called by {@link #IndexableFieldDef(String, Field, Class)} to determine the doc value
* type used by this field. Fields are not necessarily limited to one doc value, but this should
* represent the primary value that will be accessible to scripts and search through {@link
* #getDocValues(LeafReaderContext)}. A value of NONE implies that the field does not support doc
* values.
*
Expand All @@ -156,8 +165,8 @@ protected DocValuesType parseDocValuesType(Field requestField) {
}

/**
* Method called by {@link #IndexableFieldDef(String, Field)} to determine the facet value type
* for this field. The result of this method is exposed externally through {@link
* Method called by {@link #IndexableFieldDef(String, Field, Class)} to determine the facet value
* type for this field. The result of this method is exposed externally through {@link
* #getFacetValueType()}. A value of NO_FACETS implies that the field does not support facets.
*
* @param requestField field from request
Expand All @@ -168,12 +177,12 @@ protected FacetValueType parseFacetValueType(Field requestField) {
}

/**
* Method called by {@link #IndexableFieldDef(String, Field)} to set the search properties on the
* given {@link FieldType}. The {@link FieldType#setStored(boolean)} has already been set to the
* value from {@link Field#getStore()}. This method should set any other needed properties, such
* as index options, tokenization, term vectors, etc. It likely should not set a doc value type,
* as those are usually added separately. The common use of this {@link FieldType} is to add a
* {@link FieldWithData} during indexing. This method should not freeze the field type.
* Method called by {@link #IndexableFieldDef(String, Field, Class)} to set the search properties
* on the given {@link FieldType}. The {@link FieldType#setStored(boolean)} has already been set
* to the value from {@link Field#getStore()}. This method should set any other needed properties,
* such as index options, tokenization, term vectors, etc. It likely should not set a doc value
* type, as those are usually added separately. The common use of this {@link FieldType} is to add
* a {@link FieldWithData} during indexing. This method should not freeze the field type.
*
* @param fieldType type that needs search properties set
* @param requestField field from request
Expand Down Expand Up @@ -242,7 +251,7 @@ public boolean getEagerGlobalOrdinals() {
*
* @return child map
*/
public Map<String, IndexableFieldDef> getChildFields() {
public Map<String, IndexableFieldDef<?>> getChildFields() {
return childFields;
}

Expand All @@ -255,10 +264,19 @@ public Map<String, IndexableFieldDef> getChildFields() {
* @return doc values for field
* @throws IOException if there is an error loading doc values
*/
public LoadedDocValues<?> getDocValues(LeafReaderContext context) throws IOException {
public LoadedDocValues<? extends T> getDocValues(LeafReaderContext context) throws IOException {
throw new UnsupportedOperationException("Doc values not supported for field: " + getName());
}

/**
* Get the class of the doc values object for this field.
*
* @return class of doc values object
*/
public Class<? super T> getDocValuesObjectClass() {
return docValuesObjectClass;
}

/**
* Transform a value from this fields index stored fields to a {@link
* SearchResponse.Hit.FieldValue}. This will be called once for each value that was stored.
Expand Down
Loading

0 comments on commit 1155762

Please sign in to comment.