diff options
author | Geir Storli <geirstorli@yahoo.no> | 2017-03-31 15:11:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-31 15:11:18 +0200 |
commit | 3f41f672394d901a77479145e57dc4f846a30733 (patch) | |
tree | 45c93155c21d5b47b9b5ce3681dd2c45243086c4 /config-model | |
parent | f534812fc2766c11b89326e1398143bab033a67d (diff) | |
parent | 74c9fc4a3ba324d39bf754fdad83718c56de8ca4 (diff) |
Merge pull request #2111 from yahoo/bjorncs/summary-config-imported-fields
Bjorncs/summary config imported fields
Diffstat (limited to 'config-model')
17 files changed, 284 insertions, 21 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/ImmutableSearch.java b/config-model/src/main/java/com/yahoo/searchdefinition/ImmutableSearch.java index 97bf510c1a5..de23cef447f 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/ImmutableSearch.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/ImmutableSearch.java @@ -2,7 +2,9 @@ package com.yahoo.searchdefinition; import com.yahoo.searchdefinition.document.ImmutableSDField; +import com.yahoo.vespa.documentmodel.SummaryField; +import java.util.Map; import java.util.stream.Stream; /** @@ -18,4 +20,6 @@ public interface ImmutableSearch { ImmutableSDField getField(String name); Stream<ImmutableSDField> allFields(); + + Map<String, SummaryField> getSummaryFields(ImmutableSDField field); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/Search.java b/config-model/src/main/java/com/yahoo/searchdefinition/Search.java index 2dfcb3c8dde..29e67479950 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/Search.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/Search.java @@ -198,11 +198,7 @@ public class Search implements Serializable, ImmutableSearch { @Override public ImmutableSDField getField(String name) { - ImmutableSDField field = getExtraField(name); - if (field != null) { - return field; - } - field = (ImmutableSDField)docType.getField(name); + ImmutableSDField field = getConcreteField(name); if (field != null) { return field; } @@ -512,7 +508,8 @@ public class Search implements Serializable, ImmutableSearch { * @param field The source field. * @return The map of summary fields found. */ - public Map<String, SummaryField> getSummaryFields(SDField field) { + @Override + public Map<String, SummaryField> getSummaryFields(ImmutableSDField field) { Map<String, SummaryField> summaryFields = new java.util.LinkedHashMap<>(); for (DocumentSummary documentSummary : summaries.values()) { for (SummaryField summaryField : documentSummary.getSummaryFields()) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java index 1da7206ef3b..d1bb090a797 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java @@ -67,7 +67,6 @@ public class AttributeFields extends Derived implements AttributesConfig.Produce /** * Derives one attribute. TODO: Support non-default named attributes - * @param field */ private void deriveAttributes(ImmutableSDField field) { for (Attribute fieldAttribute : field.getAttributes().values()) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFields.java new file mode 100644 index 00000000000..c9ea7fb9d1f --- /dev/null +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFields.java @@ -0,0 +1,43 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.processing; + +import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.searchdefinition.RankProfileRegistry; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.ImmutableSDField; +import com.yahoo.vespa.documentmodel.SummaryField; +import com.yahoo.vespa.documentmodel.SummaryTransform; +import com.yahoo.vespa.model.container.search.QueryProfiles; + +import java.util.stream.Stream; + +/** + * Adds the attribute summary transform ({@link SummaryTransform#ATTRIBUTE} to all {@link SummaryField} having an imported + * field as source. + * + * @author bjorncs + */ +public class AddAttributeTransformToSummaryOfImportedFields extends Processor { + + public AddAttributeTransformToSummaryOfImportedFields(Search search, + DeployLogger deployLogger, + RankProfileRegistry rankProfileRegistry, + QueryProfiles queryProfiles) { + super(search, deployLogger, rankProfileRegistry, queryProfiles); + } + + @Override + public void process() { + search.allImportedFields() + .flatMap(this::getSummaryFieldsForImportedField) + .forEach(AddAttributeTransformToSummaryOfImportedFields::setAttributeTransform); + } + + private Stream<SummaryField> getSummaryFieldsForImportedField(ImmutableSDField importedField) { + return search.getSummaryFields(importedField).values().stream(); + } + + private static void setAttributeTransform(SummaryField summaryField) { + summaryField.setTransform(SummaryTransform.ATTRIBUTE); + } +} diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java index 091bf662460..9588c08439b 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java @@ -8,6 +8,7 @@ import com.yahoo.document.Field; import com.yahoo.document.PositionDataType; import com.yahoo.searchdefinition.Search; import com.yahoo.searchdefinition.document.Attribute; +import com.yahoo.searchdefinition.document.ImmutableSDField; import com.yahoo.searchdefinition.document.SDDocumentType; import com.yahoo.searchdefinition.document.SDField; import com.yahoo.vespa.documentmodel.SummaryField; @@ -58,12 +59,14 @@ public class AddExtraFieldsToDocument extends Processor { private void addSummaryField(Search search, SDDocumentType document, SummaryField field) { Field docField = document.getField(field.getName()); if (docField == null) { - SDField newField = search.getConcreteField(field.getName()); - if (newField == null) { - newField = new SDField(document, field.getName(), field.getDataType(), field.isHeader(), true); + ImmutableSDField existingField = search.getField(field.getName()); + if (existingField == null) { + SDField newField = new SDField(document, field.getName(), field.getDataType(), field.isHeader(), true); newField.setIsExtraField(true); + document.addField(newField); + } else if (!existingField.isImportedField()) { + document.addField(existingField.asField()); } - document.addField(newField); } else if (!docField.getDataType().equals(field.getDataType())) { throw newProcessException(search, field, "Summary field has conflicting type."); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/Processing.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/Processing.java index 0f6ed328ea9..2098d0c0808 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/Processing.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/Processing.java @@ -41,11 +41,13 @@ public class Processing { CreatePositionZCurve::new, WordMatch::new, DeprecateAttributePrefetch::new, + ImportedFieldsResolver::new, ImplicitSummaries::new, ImplicitSummaryFields::new, SummaryConsistency::new, SummaryNamesFieldCollisions::new, SummaryFieldsMustHaveValidSource::new, + AddAttributeTransformToSummaryOfImportedFields::new, MakeDefaultSummaryTheSuperSet::new, Bolding::new, AttributeProperties::new, @@ -63,7 +65,6 @@ public class Processing { ValidateFieldTypes::new, DisallowComplexMapAndWsetKeyTypes::new, SortingSettings::new, - ImportedFieldsResolver::new, FieldSetValidity::new, AddExtraFieldsToDocument::new, PredicateProcessor::new, diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java index 0dacb3064ec..ce1fe9e951e 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java @@ -57,14 +57,15 @@ public class SummaryFieldsMustHaveValidSource extends Processor { } } - private boolean isNotInThisSummaryClass(DocumentSummary summary, String name) { + private static boolean isNotInThisSummaryClass(DocumentSummary summary, String name) { return summary.getSummaryField(name) == null; } - private boolean isInThisSummaryClass(DocumentSummary summary, String name) { + + private static boolean isInThisSummaryClass(DocumentSummary summary, String name) { return summary.getSummaryField(name) != null; } private boolean isDocumentField(String name) { - return search.getConcreteField(name) != null; + return search.getField(name) != null; } private boolean isSummaryField(String name) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java index 63610fd623c..6bda869828f 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java @@ -2,12 +2,11 @@ package com.yahoo.searchdefinition.processing; import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.document.DataType; import com.yahoo.document.TensorDataType; import com.yahoo.searchdefinition.RankProfileRegistry; -import com.yahoo.searchdefinition.document.Attribute; -import com.yahoo.document.DataType; -import com.yahoo.searchdefinition.document.SDField; import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.Attribute; import com.yahoo.vespa.documentmodel.DocumentSummary; import com.yahoo.vespa.documentmodel.SummaryField; import com.yahoo.vespa.model.container.search.QueryProfiles; @@ -32,12 +31,12 @@ public class ValidateFieldTypes extends Processor { public void process() { String searchName = search.getName(); Map<String, DataType> seenFields = new HashMap<>(); - for (SDField field : search.allConcreteFields()) { + search.allFields().forEach(field -> { checkFieldType(searchName, "index field", field.getName(), field.getDataType(), seenFields); for (Map.Entry<String, Attribute> entry : field.getAttributes().entrySet()) { checkFieldType(searchName, "attribute", entry.getKey(), entry.getValue().getDataType(), seenFields); } - } + }); for (DocumentSummary summary : search.getSummaries().values()) { for (SummaryField field : summary.getSummaryFields()) { checkFieldType(searchName, "summary field", field.getName(), field.getDataType(), seenFields); @@ -57,7 +56,7 @@ public class ValidateFieldTypes extends Processor { } } - private boolean compatibleTypes(DataType seenType, DataType fieldType) { + private static boolean compatibleTypes(DataType seenType, DataType fieldType) { // legacy tag field type compatibility; probably not needed any more (Oct 2016) if ("tag".equals(seenType.getName())) { return "tag".equals(fieldType.getName()) || "WeightedSet<string>".equals(fieldType.getName()); diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java index cb5f5d0a1ed..684a3abe2b2 100644 --- a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryField.java @@ -249,6 +249,9 @@ public class SummaryField extends Field implements Cloneable, TypedKey { } public boolean hasSource(String name) { + if (sources.isEmpty() && name.equals(getName())) { + return true; + } for (Source s : sources) { if (s.getName().equals(name)) { return true; diff --git a/config-model/src/test/derived/importedfields/ad.sd b/config-model/src/test/derived/importedfields/ad.sd index 7bd5de13607..7c43538e501 100644 --- a/config-model/src/test/derived/importedfields/ad.sd +++ b/config-model/src/test/derived/importedfields/ad.sd @@ -9,4 +9,10 @@ search ad { fieldset myfieldset { fields: my_budget, my_person_name } + + document-summary mysummary { + summary campaign_ref type reference<campaign> {} + summary my_budget type int {} + summary my_person_name type string {} + } } diff --git a/config-model/src/test/derived/importedfields/summary.cfg b/config-model/src/test/derived/importedfields/summary.cfg new file mode 100644 index 00000000000..35d5549d333 --- /dev/null +++ b/config-model/src/test/derived/importedfields/summary.cfg @@ -0,0 +1,31 @@ +defaultsummaryid 1379505517 +classes[].id 1379505517 +classes[].name "default" +classes[].fields[].name "rankfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "summaryfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "my_budget" +classes[].fields[].type "integer" +classes[].fields[].name "my_person_name" +classes[].fields[].type "longstring" +classes[].fields[].name "documentid" +classes[].fields[].type "longstring" +classes[].id 153697641 +classes[].name "mysummary" +classes[].fields[].name "campaign_ref" +classes[].fields[].type "longstring" +classes[].fields[].name "my_budget" +classes[].fields[].type "integer" +classes[].fields[].name "my_person_name" +classes[].fields[].type "longstring" +classes[].fields[].name "rankfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "summaryfeatures" +classes[].fields[].type "featuredata" +classes[].id 1274088866 +classes[].name "attributeprefetch" +classes[].fields[].name "rankfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "summaryfeatures" +classes[].fields[].type "featuredata" diff --git a/config-model/src/test/derived/importedfields/summarymap.cfg b/config-model/src/test/derived/importedfields/summarymap.cfg new file mode 100644 index 00000000000..39408bbff5e --- /dev/null +++ b/config-model/src/test/derived/importedfields/summarymap.cfg @@ -0,0 +1,13 @@ +defaultoutputclass -1 +override[].field "rankfeatures" +override[].command "rankfeatures" +override[].arguments "" +override[].field "summaryfeatures" +override[].command "summaryfeatures" +override[].arguments "" +override[].field "my_budget" +override[].command "attribute" +override[].arguments "my_budget" +override[].field "my_person_name" +override[].command "attribute" +override[].arguments "my_person_name" diff --git a/config-model/src/test/derived/reference_fields/ad.sd b/config-model/src/test/derived/reference_fields/ad.sd index e6f084dbeed..b7ead570154 100644 --- a/config-model/src/test/derived/reference_fields/ad.sd +++ b/config-model/src/test/derived/reference_fields/ad.sd @@ -6,5 +6,11 @@ search ad { field other_ref type reference<campaign> { indexing: attribute } + field yet_another_ref type reference<campaign> { + indexing: attribute + } + } + document-summary explicit_summary { + summary yet_another_ref type reference<campaign> {} } } diff --git a/config-model/src/test/derived/reference_fields/attributes.cfg b/config-model/src/test/derived/reference_fields/attributes.cfg index f657ed2b93b..b9446c596fd 100644 --- a/config-model/src/test/derived/reference_fields/attributes.cfg +++ b/config-model/src/test/derived/reference_fields/attributes.cfg @@ -36,3 +36,22 @@ attribute[].lowerbound -9223372036854775808 attribute[].upperbound 9223372036854775807 attribute[].densepostinglistthreshold 0.4 attribute[].tensortype "" +attribute[].name "yet_another_ref" +attribute[].datatype REFERENCE +attribute[].collectiontype SINGLE +attribute[].removeifzero false +attribute[].createifnonexistent false +attribute[].fastsearch false +attribute[].huge false +attribute[].sortascending true +attribute[].sortfunction UCA +attribute[].sortstrength PRIMARY +attribute[].sortlocale "" +attribute[].enablebitvectors false +attribute[].enableonlybitvector false +attribute[].fastaccess false +attribute[].arity 8 +attribute[].lowerbound -9223372036854775808 +attribute[].upperbound 9223372036854775807 +attribute[].densepostinglistthreshold 0.4 +attribute[].tensortype "" diff --git a/config-model/src/test/derived/reference_fields/summary.cfg b/config-model/src/test/derived/reference_fields/summary.cfg index 429a179faac..49037473d88 100644 --- a/config-model/src/test/derived/reference_fields/summary.cfg +++ b/config-model/src/test/derived/reference_fields/summary.cfg @@ -9,6 +9,14 @@ classes[].fields[].name "summaryfeatures" classes[].fields[].type "featuredata" classes[].fields[].name "documentid" classes[].fields[].type "longstring" +classes[].id 428144659 +classes[].name "explicit_summary" +classes[].fields[].name "yet_another_ref" +classes[].fields[].type "longstring" +classes[].fields[].name "rankfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "summaryfeatures" +classes[].fields[].type "featuredata" classes[].id 1274088866 classes[].name "attributeprefetch" classes[].fields[].name "rankfeatures" diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java new file mode 100644 index 00000000000..19634c4cfcc --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java @@ -0,0 +1,65 @@ +package com.yahoo.searchdefinition.processing; + +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.document.DataType; +import com.yahoo.document.Field; +import com.yahoo.searchdefinition.DocumentReference; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.ImportedField; +import com.yahoo.searchdefinition.document.ImportedFields; +import com.yahoo.searchdefinition.document.SDDocumentType; +import com.yahoo.searchdefinition.document.SDField; +import com.yahoo.vespa.documentmodel.DocumentSummary; +import com.yahoo.vespa.documentmodel.SummaryField; +import com.yahoo.vespa.documentmodel.SummaryTransform; +import org.junit.Test; + +import java.util.Collections; + +import static org.junit.Assert.assertEquals; + +/** + * @author bjorncs + */ +public class AddAttributeTransformToSummaryOfImportedFieldsTest { + + private static final String IMPORTED_FIELD_NAME = "imported_myfield"; + private static final String DOCUMENT_NAME = "mydoc"; + private static final String SUMMARY_NAME = "mysummary"; + + @Test + public void attribute_summary_transform_applied_to_summary_field_of_imported_field() { + Search search = createSearchWithDocument(DOCUMENT_NAME); + search.setImportedFields(createSingleImportedField(IMPORTED_FIELD_NAME)); + search.addSummary(createDocumentSummary(IMPORTED_FIELD_NAME)); + + AddAttributeTransformToSummaryOfImportedFields processor = new AddAttributeTransformToSummaryOfImportedFields( + search,null,null,null); + processor.process(); + SummaryField summaryField = search.getSummaries().get(SUMMARY_NAME).getSummaryField(IMPORTED_FIELD_NAME); + SummaryTransform actualTransform = summaryField.getTransform(); + assertEquals(SummaryTransform.ATTRIBUTE, actualTransform); + } + + private static Search createSearchWithDocument(String documentName) { + Search search = new Search(documentName, MockApplicationPackage.createEmpty()); + SDDocumentType document = new SDDocumentType(documentName, search); + search.addDocument(document); + return search; + } + + private static ImportedFields createSingleImportedField(String fieldName) { + Search targetSearch = new Search("target_doc", MockApplicationPackage.createEmpty()); + SDField targetField = new SDField("target_field", DataType.INT); + DocumentReference documentReference = new DocumentReference(new Field("reference_field"), targetSearch); + ImportedField importedField = new ImportedField(fieldName, documentReference, targetField); + return new ImportedFields(Collections.singletonMap(fieldName, importedField)); + } + + private static DocumentSummary createDocumentSummary(String fieldName) { + DocumentSummary summary = new DocumentSummary("mysummary"); + summary.add(new SummaryField(fieldName, DataType.INT)); + return summary; + } + +} diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java new file mode 100644 index 00000000000..88d607042a3 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java @@ -0,0 +1,65 @@ +package com.yahoo.searchdefinition.processing; + +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.document.DataType; +import com.yahoo.document.Field; +import com.yahoo.searchdefinition.DocumentReference; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.ImportedField; +import com.yahoo.searchdefinition.document.ImportedFields; +import com.yahoo.searchdefinition.document.SDDocumentType; +import com.yahoo.searchdefinition.document.SDField; +import com.yahoo.vespa.documentmodel.DocumentSummary; +import com.yahoo.vespa.documentmodel.SummaryField; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Collections; + +/** + * @author bjorncs + */ +public class ValidateFieldTypesTest { + + private static final String IMPORTED_FIELD_NAME = "imported_myfield"; + private static final String DOCUMENT_NAME = "my_doc"; + + @Rule + public final ExpectedException exceptionRule = ExpectedException.none(); + + @Test + public void throws_exception_if_type_of_document_field_does_not_match_summary_field() { + Search search = createSearchWithDocument(DOCUMENT_NAME); + search.setImportedFields(createSingleImportedField(IMPORTED_FIELD_NAME, DataType.INT)); + search.addSummary(createDocumentSummary(IMPORTED_FIELD_NAME, DataType.STRING)); + + ValidateFieldTypes validator = new ValidateFieldTypes(search, null, null, null); + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage( + "For search '" + DOCUMENT_NAME + "', field '" + IMPORTED_FIELD_NAME + "': Incompatible types. " + + "Expected int for summary field '" + IMPORTED_FIELD_NAME + "', got string."); + validator.process(); + } + + private static Search createSearchWithDocument(String documentName) { + Search search = new Search(documentName, MockApplicationPackage.createEmpty()); + SDDocumentType document = new SDDocumentType(documentName, search); + search.addDocument(document); + return search; + } + + private static ImportedFields createSingleImportedField(String fieldName, DataType dataType) { + Search targetSearch = new Search("target_doc", MockApplicationPackage.createEmpty()); + SDField targetField = new SDField("target_field", dataType); + DocumentReference documentReference = new DocumentReference(new Field("reference_field"), targetSearch); + ImportedField importedField = new ImportedField(fieldName, documentReference, targetField); + return new ImportedFields(Collections.singletonMap(fieldName, importedField)); + } + + private static DocumentSummary createDocumentSummary(String fieldName, DataType dataType) { + DocumentSummary summary = new DocumentSummary("mysummary"); + summary.add(new SummaryField(fieldName, dataType)); + return summary; + } +} |