diff options
Diffstat (limited to 'config-model/src/main/java/com/yahoo/schema/processing/AdjustPositionSummaryFields.java')
-rw-r--r-- | config-model/src/main/java/com/yahoo/schema/processing/AdjustPositionSummaryFields.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/schema/processing/AdjustPositionSummaryFields.java b/config-model/src/main/java/com/yahoo/schema/processing/AdjustPositionSummaryFields.java new file mode 100644 index 00000000000..6c2d62f37cb --- /dev/null +++ b/config-model/src/main/java/com/yahoo/schema/processing/AdjustPositionSummaryFields.java @@ -0,0 +1,135 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.schema.processing; + +import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.config.model.api.ModelContext; +import com.yahoo.document.ArrayDataType; +import com.yahoo.document.DataType; +import com.yahoo.document.PositionDataType; +import com.yahoo.schema.RankProfileRegistry; +import com.yahoo.schema.Schema; +import com.yahoo.schema.document.Attribute; +import com.yahoo.schema.document.GeoPos; +import com.yahoo.schema.document.ImmutableSDField; +import com.yahoo.vespa.documentmodel.DocumentSummary; +import com.yahoo.vespa.documentmodel.SummaryField; +import com.yahoo.vespa.documentmodel.SummaryField.Source; +import com.yahoo.vespa.documentmodel.SummaryTransform; +import com.yahoo.vespa.model.container.search.QueryProfiles; + +/* + * Adjusts position summary fields by adding derived summary fields (.distance and .position) and setting summary + * transform and source. + */ +public class AdjustPositionSummaryFields extends Processor { + + public AdjustPositionSummaryFields(Schema schema, DeployLogger deployLogger, RankProfileRegistry rankProfileRegistry, QueryProfiles queryProfiles) { + super(schema, deployLogger, rankProfileRegistry, queryProfiles); + } + + private boolean useV8GeoPositions = false; + + @Override + public void process(boolean validate, boolean documentsOnly, ModelContext.Properties properties) { + this.useV8GeoPositions = properties.featureFlags().useV8GeoPositions(); + process(validate, documentsOnly); + } + + @Override + public void process(boolean validate, boolean documentsOnly) { + for (DocumentSummary summary : schema.getSummaries().values()) { + scanSummary(summary); + } + } + + private void scanSummary(DocumentSummary summary) { + for (SummaryField summaryField : summary.getSummaryFields().values()) { + if ( ! GeoPos.isAnyPos(summaryField.getDataType())) continue; + + String originalSource = summaryField.getSingleSource(); + if (originalSource.indexOf('.') == -1) { // Eliminate summary fields with pos.x or pos.y as source + ImmutableSDField sourceField = schema.getField(originalSource); + if (sourceField != null) { + String zCurve = null; + if (sourceField.getDataType().equals(summaryField.getDataType())) { + zCurve = PositionDataType.getZCurveFieldName(originalSource); + } else if (sourceField.getDataType().equals(makeZCurveDataType(summaryField.getDataType())) && + hasZCurveSuffix(originalSource)) { + zCurve = originalSource; + } + if (zCurve != null) { + if (hasPositionAttribute(zCurve)) { + Source source = new Source(zCurve); + adjustPositionField(summary, summaryField, source); + } else if (sourceField.isImportedField() || !summaryField.getName().equals(originalSource)) { + fail(summaryField, "No position attribute '" + zCurve + "'"); + } + } + } + } + } + } + + private void adjustPositionField(DocumentSummary summary, SummaryField summaryField, Source source) { + summaryField.setTransform(SummaryTransform.GEOPOS); + summaryField.getSources().clear(); + summaryField.addSource(source); + ensureSummaryField(summary, + PositionDataType.getPositionSummaryFieldName(summaryField.getName()), + DataType.getArray(DataType.STRING), + source, + SummaryTransform.POSITIONS); + ensureSummaryField(summary, + PositionDataType.getDistanceSummaryFieldName(summaryField.getName()), + DataType.INT, + source, + SummaryTransform.DISTANCE); + } + + private void ensureSummaryField(DocumentSummary summary, String fieldName, DataType dataType, Source source, SummaryTransform transform) { + SummaryField oldField = schema.getSummaryField(fieldName); + if (oldField == null) { + if (useV8GeoPositions) return; + SummaryField newField = new SummaryField(fieldName, dataType, transform); + newField.addSource(source); + summary.add(newField); + return; + } + if (!oldField.getDataType().equals(dataType)) { + fail(oldField, "exists with type '" + oldField.getDataType().toString() + "', should be of type '" + dataType.toString() + "'"); + } + if (oldField.getTransform() != transform) { + fail(oldField, "has summary transform '" + oldField.getTransform().toString() + "', should have transform '" + transform.toString() + "'"); + } + if (oldField.getSourceCount() != 1 || !oldField.getSingleSource().equals(source.getName())) { + fail(oldField, "has source '" + oldField.getSources().toString() + "', should have source '" + source + "'"); + } + if (useV8GeoPositions) return; + summary.add(oldField); + } + + private boolean hasPositionAttribute(String name) { + Attribute attribute = schema.getAttribute(name); + if (attribute == null) { + ImmutableSDField field = schema.getField(name); + if (field != null && field.isImportedField()) { + attribute = field.getAttribute(); + } + } + return attribute != null && attribute.isPosition(); + } + + private static boolean hasZCurveSuffix(String name) { + String suffix = PositionDataType.getZCurveFieldName(""); + return name.length() > suffix.length() && name.substring(name.length() - suffix.length()).equals(suffix); + } + + private static DataType makeZCurveDataType(DataType dataType) { + return dataType instanceof ArrayDataType ? DataType.getArray(DataType.LONG) : DataType.LONG; + } + + private void fail(SummaryField summaryField, String msg) { + throw newProcessException(schema.getName(), summaryField.getName(), msg); + } + +} |