diff options
author | Tor Egge <Tor.Egge@oath.com> | 2018-12-04 12:49:27 +0000 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2018-12-05 16:51:21 +0100 |
commit | 00ad57b13f501d22d4ebbfa5281cfc7a0677833c (patch) | |
tree | 701cb378af34f89e6a414c2198058eb2f18e2996 /config-model | |
parent | 200663867930d081a49644c42f6090a926a327c3 (diff) |
Process position summary entries.
Diffstat (limited to 'config-model')
12 files changed, 562 insertions, 42 deletions
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 index c10b52eb1e6..e324944549c 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFields.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFields.java @@ -44,7 +44,9 @@ public class AddAttributeTransformToSummaryOfImportedFields extends Processor { } private static void setAttributeTransform(SummaryField summaryField) { - summaryField.setTransform(SummaryTransform.ATTRIBUTE); + if (summaryField.getTransform() == SummaryTransform.NONE) { + summaryField.setTransform(SummaryTransform.ATTRIBUTE); + } } private static void setAttributeCombinerTransform(SummaryField summaryField) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java new file mode 100644 index 00000000000..e847a5428c0 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java @@ -0,0 +1,127 @@ +// Copyright 2018 Yahoo Holdings. 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.document.DataType; +import com.yahoo.document.PositionDataType; +import com.yahoo.searchdefinition.RankProfileRegistry; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.Attribute; +import com.yahoo.searchdefinition.document.ImmutableImportedSDField; +import com.yahoo.searchdefinition.document.ImmutableSDField; +import com.yahoo.searchdefinition.document.ImportedField; +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; + +import java.util.LinkedList; +import java.util.List; + +/* + * 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(Search search, DeployLogger deployLogger, RankProfileRegistry rankProfileRegistry, QueryProfiles queryProfiles) { + super(search, deployLogger, rankProfileRegistry, queryProfiles); + } + + @Override + public void process(boolean validate, boolean documentsOnly) { + List<SummaryField> fixupFields = new LinkedList<SummaryField>(); + for (DocumentSummary summary : search.getSummaries().values()) { + scanSummary(summary, fixupFields); + } + for (SummaryField summaryField : fixupFields) { + String originalSource = summaryField.getSingleSource(); + summaryField.getSources().clear(); + summaryField.addSource(PositionDataType.getZCurveFieldName(originalSource)); + } + } + + private void scanSummary(DocumentSummary summary, List<SummaryField> fixupFields) { + for (SummaryField summaryField : summary.getSummaryFields()) { + if (isPositionDataType(summaryField.getDataType())) { + String originalSource = summaryField.getSingleSource(); + ImmutableSDField sourceField = getSourceField(originalSource); + if (sourceField != null && sourceField.getDataType().equals(summaryField.getDataType())) { + String zCurve = PositionDataType.getZCurveFieldName(originalSource); + if (hasPositionAttribute(zCurve)) { + Source source = new Source(zCurve); + adjustPositionField(summary, summaryField, source); + fixupFields.add(summaryField); + } else { + fail(summaryField, "No position attribute '" + zCurve + "'"); + } + } + } + } + } + + private void adjustPositionField(DocumentSummary summary, SummaryField summaryField, Source source) { + if (summaryField.getTransform() == SummaryTransform.NONE) { + summaryField.setTransform(SummaryTransform.GEOPOS); + } + 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 = search.getSummaryField(fieldName); + if (oldField == null) { + 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 + "'"); + } + summary.add(oldField); + } + + private ImmutableSDField getSourceField(String name) { + ImmutableSDField field = search.getField(name); + if (field == null && search.importedFields().isPresent()) { + ImportedField importedField = search.importedFields().get().complexFields().get(name); + if (importedField != null) { + field = new ImmutableImportedSDField(importedField); + } + } + return field; + } + + private boolean hasPositionAttribute(String name) { + Attribute attribute = search.getAttribute(name); + if (attribute == null) { + ImmutableSDField field = search.getField(name); + if (field != null && field.isImportedField()) { + while (field.isImportedField()) { + field = field.getBackingField(); + } + attribute = field.getAttributes().get(field.getName()); + } + } + return attribute != null && attribute.isPosition(); + } + + private static boolean isPositionDataType(DataType dataType) { + return dataType.equals(PositionDataType.INSTANCE) || dataType.equals(DataType.getArray(PositionDataType.INSTANCE)); + } + + private void fail(SummaryField summaryField, String msg) { + throw newProcessException(search.getName(), summaryField.getName(), msg); + } + +} 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 062b82bd230..8396139861d 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 @@ -43,6 +43,7 @@ public class Processing { ImportedFieldsResolver::new, ImplicitSummaries::new, ImplicitSummaryFields::new, + AdjustPositionSummaryFields::new, SummaryConsistency::new, SummaryNamesFieldCollisions::new, SummaryFieldsMustHaveValidSource::new, diff --git a/config-model/src/test/derived/imported_position_field_summary/child.sd b/config-model/src/test/derived/imported_position_field_summary/child.sd new file mode 100644 index 00000000000..aaa31a3273d --- /dev/null +++ b/config-model/src/test/derived/imported_position_field_summary/child.sd @@ -0,0 +1,13 @@ +# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +search child { + document child { + field parent_ref type reference<parent> { + indexing: attribute | summary + } + } + import field parent_ref.pos as my_pos {} + + document-summary mysummary { + summary my_pos type position { } + } +} diff --git a/config-model/src/test/derived/imported_position_field_summary/index-info.cfg b/config-model/src/test/derived/imported_position_field_summary/index-info.cfg new file mode 100644 index 00000000000..c87553d6537 --- /dev/null +++ b/config-model/src/test/derived/imported_position_field_summary/index-info.cfg @@ -0,0 +1,43 @@ +indexinfo[].name "child" +indexinfo[].command[].indexname "sddocname" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "sddocname" +indexinfo[].command[].command "word" +indexinfo[].command[].indexname "parent_ref" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "parent_ref" +indexinfo[].command[].command "attribute" +indexinfo[].command[].indexname "parent_ref" +indexinfo[].command[].command "word" +indexinfo[].command[].indexname "my_pos.x" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos.x" +indexinfo[].command[].command "numerical" +indexinfo[].command[].indexname "my_pos.y" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos.y" +indexinfo[].command[].command "numerical" +indexinfo[].command[].indexname "my_pos" +indexinfo[].command[].command "default-position" +indexinfo[].command[].indexname "my_pos" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos.distance" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos.distance" +indexinfo[].command[].command "numerical" +indexinfo[].command[].indexname "my_pos.position" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos.position" +indexinfo[].command[].command "multivalue" +indexinfo[].command[].indexname "rankfeatures" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "summaryfeatures" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos_zcurve" +indexinfo[].command[].command "index" +indexinfo[].command[].indexname "my_pos_zcurve" +indexinfo[].command[].command "attribute" +indexinfo[].command[].indexname "my_pos_zcurve" +indexinfo[].command[].command "fast-search" +indexinfo[].command[].indexname "my_pos_zcurve" +indexinfo[].command[].command "numerical" diff --git a/config-model/src/test/derived/imported_position_field_summary/parent.sd b/config-model/src/test/derived/imported_position_field_summary/parent.sd new file mode 100644 index 00000000000..493e105e5fd --- /dev/null +++ b/config-model/src/test/derived/imported_position_field_summary/parent.sd @@ -0,0 +1,8 @@ +# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +search parent { + document parent { + field pos type position { + indexing: attribute | summary + } + } +} diff --git a/config-model/src/test/derived/imported_position_field_summary/summary.cfg b/config-model/src/test/derived/imported_position_field_summary/summary.cfg new file mode 100644 index 00000000000..b607786ca36 --- /dev/null +++ b/config-model/src/test/derived/imported_position_field_summary/summary.cfg @@ -0,0 +1,35 @@ +defaultsummaryid 1194448774 +classes[].id 1194448774 +classes[].name "default" +classes[].fields[].name "parent_ref" +classes[].fields[].type "longstring" +classes[].fields[].name "rankfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "summaryfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "my_pos" +classes[].fields[].type "jsonstring" +classes[].fields[].name "my_pos.position" +classes[].fields[].type "xmlstring" +classes[].fields[].name "my_pos.distance" +classes[].fields[].type "integer" +classes[].fields[].name "documentid" +classes[].fields[].type "longstring" +classes[].id 890647799 +classes[].name "mysummary" +classes[].fields[].name "my_pos" +classes[].fields[].type "jsonstring" +classes[].fields[].name "rankfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "summaryfeatures" +classes[].fields[].type "featuredata" +classes[].fields[].name "my_pos.position" +classes[].fields[].type "xmlstring" +classes[].fields[].name "my_pos.distance" +classes[].fields[].type "integer" +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/imported_position_field_summary/summarymap.cfg b/config-model/src/test/derived/imported_position_field_summary/summarymap.cfg new file mode 100644 index 00000000000..e2c0b546a59 --- /dev/null +++ b/config-model/src/test/derived/imported_position_field_summary/summarymap.cfg @@ -0,0 +1,16 @@ +defaultoutputclass -1 +override[].field "my_pos" +override[].command "geopos" +override[].arguments "my_pos_zcurve" +override[].field "rankfeatures" +override[].command "rankfeatures" +override[].arguments "" +override[].field "summaryfeatures" +override[].command "summaryfeatures" +override[].arguments "" +override[].field "my_pos.position" +override[].command "positions" +override[].arguments "my_pos_zcurve" +override[].field "my_pos.distance" +override[].command "absdist" +override[].arguments "my_pos_zcurve" diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java index b4c42c248ef..b06745f9a75 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java @@ -25,4 +25,9 @@ public class ImportedFieldsTestCase extends AbstractExportingTestCase { public void configs_for_imported_position_field_are_derived() throws IOException, ParseException { assertCorrectDeriving("imported_position_field", "child"); } + + @Test + public void configs_for_imported_position_field_summary_are_derived() throws IOException, ParseException { + assertCorrectDeriving("imported_position_field_summary", "child"); + } } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFieldsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFieldsTestCase.java new file mode 100644 index 00000000000..00df42d60c3 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFieldsTestCase.java @@ -0,0 +1,244 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.processing; + +import com.google.common.collect.ImmutableMap; +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.document.DataType; +import com.yahoo.document.PositionDataType; +import com.yahoo.document.ReferenceDataType; +import com.yahoo.document.TemporaryStructuredDataType; +import com.yahoo.searchdefinition.DocumentReference; +import com.yahoo.searchdefinition.DocumentReferences; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.SDDocumentType; +import com.yahoo.searchdefinition.document.SDField; +import com.yahoo.searchdefinition.document.TemporaryImportedField; +import com.yahoo.searchdefinition.document.TemporarySDField; +import com.yahoo.vespa.documentmodel.DocumentSummary; +import com.yahoo.vespa.documentmodel.SummaryField; +import com.yahoo.vespa.documentmodel.SummaryTransform; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class AdjustPositionSummaryFieldsTestCase { + + @Test + public void test_pos_summary() { + SearchModel model = new SearchModel(false); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, "pos"); + model.resolve(); + model.assertSummaryField("my_pos", PositionDataType.INSTANCE, SummaryTransform.GEOPOS, "pos_zcurve"); + model.assertSummaryField("my_pos.position", DataType.getArray(DataType.STRING), SummaryTransform.POSITIONS, "pos_zcurve"); + model.assertSummaryField("my_pos.distance", DataType.INT, SummaryTransform.DISTANCE, "pos_zcurve"); + } + + @Test + public void test_imported_pos_summary() { + SearchModel model = new SearchModel(); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, null); + model.resolve(); + model.assertSummaryField("my_pos", PositionDataType.INSTANCE, SummaryTransform.GEOPOS, "my_pos_zcurve"); + model.assertSummaryField("my_pos.position", DataType.getArray(DataType.STRING), SummaryTransform.POSITIONS, "my_pos_zcurve"); + model.assertSummaryField("my_pos.distance", DataType.INT, SummaryTransform.DISTANCE, "my_pos_zcurve"); + } + + @Test + public void test_imported_pos_summary_bad_source() { + SearchModel model = new SearchModel(); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, "pos"); + model.resolve(); + model.assertSummaryField("my_pos", PositionDataType.INSTANCE, SummaryTransform.NONE, "pos"); + model.assertNoSummaryField("my_pos.position"); + model.assertNoSummaryField("my_pos.distance"); + } + + @Test + public void test_imported_pos_summary_bad_datatype() { + SearchModel model = new SearchModel(); + model.addSummaryField("my_pos", DataType.getArray(PositionDataType.INSTANCE), null, "pos"); + model.resolve(); + model.assertSummaryField("my_pos", DataType.getArray(PositionDataType.INSTANCE), SummaryTransform.NONE, "pos"); + model.assertNoSummaryField("my_pos.position"); + model.assertNoSummaryField("my_pos.distance"); + } + + @Rule + public final ExpectedException exceptionRule = ExpectedException.none(); + + @Test + public void test_pos_summary_no_attr() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', field 'my_pos': " + + "No position attribute 'pos_zcurve'"); + SearchModel model = new SearchModel(false, false, false); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, "pos"); + model.resolve(); + } + + @Test + public void test_pos_summary_bad_attr() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', field 'my_pos': " + + "No position attribute 'pos_zcurve'"); + SearchModel model = new SearchModel(false, false, true); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, "pos"); + model.resolve(); + } + + @Test + public void test_imported_pos_summary_no_attr() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', import field 'my_pos_zcurve': " + + "Field 'pos_zcurve' via reference field 'ref': Not found"); + SearchModel model = new SearchModel(true, false, false); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, null); + model.resolve(); + } + + @Test + public void test_imported_pos_summary_bad_attr() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', field 'my_pos': " + + "No position attribute 'my_pos_zcurve'"); + SearchModel model = new SearchModel(true, false, true); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, null); + model.resolve(); + } + + @Test + public void test_my_pos_position_summary_bad_datatype() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', field 'my_pos.position': " + + "exists with type 'datatype string (code: 2)', should be of type 'datatype Array<string> (code: -1486737430)"); + SearchModel model = new SearchModel(); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, null); + model.addSummaryField("my_pos.position", DataType.STRING, null, "pos"); + model.resolve(); + } + + @Test + public void test_my_pos_position_summary_bad_transform() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', field 'my_pos.position': " + + "has summary transform 'none', should have transform 'positions'"); + SearchModel model = new SearchModel(); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, null); + model.addSummaryField("my_pos.position", DataType.getArray(DataType.STRING), null, "pos"); + model.resolve(); + } + + @Test + public void test_my_pos_position_summary_bad_source() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage("For search 'child', field 'my_pos.position': " + + "has source '[source field 'pos']', should have source 'source field 'my_pos_zcurve''"); + SearchModel model = new SearchModel(); + model.addSummaryField("my_pos", PositionDataType.INSTANCE, null, null); + model.addSummaryField("my_pos.position", DataType.getArray(DataType.STRING), SummaryTransform.POSITIONS, "pos"); + model.resolve(); + } + + static class SearchModel extends ParentChildSearchModel { + + public SearchModel() { + this(true); + } + + public SearchModel(boolean importedPos) { + this(importedPos, true, false); + } + + public SearchModel(boolean importedPos, boolean setupPosAttr, boolean setupBadAttr) { + super(); + if (importedPos) { + createPositionField(parentSearch, setupPosAttr, setupBadAttr); + } + addRefField(childSearch, parentSearch, "ref"); + if (importedPos) { + addImportedField("my_pos", "ref", "pos"); + } else { + createPositionField(childSearch, setupPosAttr, setupBadAttr); + } + } + + private void createPositionField(Search search, boolean setupPosAttr, boolean setupBadAttr) { + String ilScript = setupPosAttr ? "{ summary | attribute }" : "{ summary }"; + search.getDocument().addField(createField("pos", PositionDataType.INSTANCE, ilScript)); + if (setupBadAttr) { + search.getDocument().addField(createField("pos_zcurve", DataType.LONG, "{ attribute }")); + } + } + + public void addSummaryField(String fieldName, DataType dataType, SummaryTransform transform, String source) { + addSummaryField("my_summary", fieldName, dataType, transform, source); + } + + public void addSummaryField(String summaryName, String fieldName, DataType dataType, SummaryTransform transform, String source) { + DocumentSummary summary = childSearch.getSummary(summaryName); + if (summary == null) { + summary = new DocumentSummary(summaryName); + childSearch.addSummary(summary); + } + SummaryField summaryField = new SummaryField(fieldName, dataType); + if (source != null) { + summaryField.addSource(source); + } + if (transform != null) { + summaryField.setTransform(transform); + } + summary.add(summaryField); + } + + public void assertNoSummaryField(String fieldName) { + assertNoSummaryField("my_summary", fieldName); + } + + public void assertNoSummaryField(String summaryName, String fieldName) { + DocumentSummary summary = childSearch.getSummary(summaryName); + assertNotNull(summary); + SummaryField summaryField = summary.getSummaryField(fieldName); + assertNull(summaryField); + } + + public void assertSummaryField(String fieldName, DataType dataType, SummaryTransform transform, String source) { + assertSummaryField("my_summary", fieldName, dataType, transform, source); + } + + public void assertSummaryField(String summaryName, String fieldName, DataType dataType, SummaryTransform transform, String source) { + DocumentSummary summary = childSearch.getSummary(summaryName); + assertNotNull(summary); + SummaryField summaryField = summary.getSummaryField(fieldName); + assertNotNull(summaryField); + assertEquals(dataType, summaryField.getDataType()); + assertEquals(transform, summaryField.getTransform()); + if (source == null) { + assertEquals(0, summaryField.getSourceCount()); + } else { + assertEquals(1, summaryField.getSourceCount()); + assertEquals(source, summaryField.getSingleSource()); + } + } + + public void resolve() { + resolve(parentSearch); + resolve(childSearch); + } + + private static void resolve(Search search) { + new CreatePositionZCurve(search, null, null, null).process(true, false); + assertNotNull(search.temporaryImportedFields().get()); + assertFalse(search.importedFields().isPresent()); + new ImportedFieldsResolver(search, null, null, null).process(true, false); + assertFalse(search.temporaryImportedFields().isPresent()); + assertNotNull(search.importedFields().get()); + new AdjustPositionSummaryFields(search, null, null, null).process(true, false); + } + } +} diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java index de08bf66548..3e3cd932e55 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java @@ -112,19 +112,16 @@ public class ImportedFieldsResolverTestCase { new SearchModel().addImportedField("my_predicate_field", "ref", "predicate_field").resolve(); } - static class SearchModel { + static class SearchModel extends ParentChildSearchModel { - private final ApplicationPackage app = MockApplicationPackage.createEmpty(); public final Search grandParentSearch; - public final Search parentSearch; - public final Search childSearch; public ImportedFields importedFields; public SearchModel() { + super(); grandParentSearch = createSearch("grandparent"); grandParentSearch.getDocument().addField(createField("ancient_field", DataType.INT, "{ attribute }")); - parentSearch = createSearch("parent"); parentSearch.getDocument().addField(createField("attribute_field", DataType.INT, "{ attribute }")); parentSearch.getDocument().addField(createField("attribute_and_index", DataType.INT, "{ attribute | index }")); parentSearch.getDocument().addField(new TemporarySDField("not_attribute", DataType.INT)); @@ -133,49 +130,16 @@ public class ImportedFieldsResolverTestCase { addRefField(parentSearch, grandParentSearch, "ref"); addImportedField(parentSearch, "ancient_field", "ref", "ancient_field"); - childSearch = createSearch("child"); addRefField(childSearch, parentSearch, "ref"); } - private Search createSearch(String name) { - Search result = new Search(name, app); - result.addDocument(new SDDocumentType(name)); - return result; - } - - private static TemporarySDField createField(String name, DataType dataType, String indexingScript) { - TemporarySDField result = new TemporarySDField(name, dataType); - result.parseIndexingScript(indexingScript); - return result; - } - - private static SDField createRefField(String parentType, String fieldName) { - return new TemporarySDField(fieldName, ReferenceDataType.createWithInferredId(TemporaryStructuredDataType.create(parentType))); - } - private static void addRefField(Search child, Search parent, String fieldName) { - SDField refField = createRefField(parent.getName(), fieldName); - child.getDocument().addField(refField); - child.getDocument().setDocumentReferences(new DocumentReferences(ImmutableMap.of(refField.getName(), - new DocumentReference(refField, parent)))); - } - - public SearchModel addImportedField(String fieldName, String referenceFieldName, String targetFieldName) { + protected SearchModel addImportedField(String fieldName, String referenceFieldName, String targetFieldName) { return addImportedField(childSearch, fieldName, referenceFieldName, targetFieldName); } - private SearchModel addImportedField(Search search, String fieldName, String referenceFieldName, String targetFieldName) { - search.temporaryImportedFields().get().add(new TemporaryImportedField(fieldName, referenceFieldName, targetFieldName)); - return this; - } - - public SearchModel addSummaryField(String fieldName, DataType dataType) { - DocumentSummary summary = childSearch.getSummary("my_summary"); - if (summary == null) { - summary = new DocumentSummary("my_summary"); - childSearch.addSummary(summary); - } - summary.add(new SummaryField(fieldName, dataType)); + protected SearchModel addImportedField(Search search, String fieldName, String referenceFieldName, String targetFieldName) { + super.addImportedField(search, fieldName, referenceFieldName, targetFieldName); return this; } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java new file mode 100644 index 00000000000..7d6a8507dd3 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java @@ -0,0 +1,62 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.processing; + +import com.google.common.collect.ImmutableMap; +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.document.DataType; +import com.yahoo.document.ReferenceDataType; +import com.yahoo.document.TemporaryStructuredDataType; +import com.yahoo.searchdefinition.DocumentReference; +import com.yahoo.searchdefinition.DocumentReferences; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.SDDocumentType; +import com.yahoo.searchdefinition.document.SDField; +import com.yahoo.searchdefinition.document.TemporaryImportedField; +import com.yahoo.searchdefinition.document.TemporarySDField; + +/* + * Fixture class used for ImportedFieldsResolverTestCase and AdjustPositionSummaryFieldsTestCase. + */ +public class ParentChildSearchModel { + private final ApplicationPackage app = MockApplicationPackage.createEmpty(); + public Search parentSearch; + public Search childSearch; + + ParentChildSearchModel() { + parentSearch = createSearch("parent"); + childSearch = createSearch("child"); + } + + protected Search createSearch(String name) { + Search result = new Search(name, app); + result.addDocument(new SDDocumentType(name)); + return result; + } + + protected static TemporarySDField createField(String name, DataType dataType, String indexingScript) { + TemporarySDField result = new TemporarySDField(name, dataType); + result.parseIndexingScript(indexingScript); + return result; + } + + protected static SDField createRefField(String parentType, String fieldName) { + return new TemporarySDField(fieldName, ReferenceDataType.createWithInferredId(TemporaryStructuredDataType.create(parentType))); + } + + protected static void addRefField(Search child, Search parent, String fieldName) { + SDField refField = createRefField(parent.getName(), fieldName); + child.getDocument().addField(refField); + child.getDocument().setDocumentReferences(new DocumentReferences(ImmutableMap.of(refField.getName(), + new DocumentReference(refField, parent)))); + } + + protected ParentChildSearchModel addImportedField(String fieldName, String referenceFieldName, String targetFieldName) { + return addImportedField(childSearch, fieldName, referenceFieldName, targetFieldName); + } + + protected ParentChildSearchModel addImportedField(Search search, String fieldName, String referenceFieldName, String targetFieldName) { + search.temporaryImportedFields().get().add(new TemporaryImportedField(fieldName, referenceFieldName, targetFieldName)); + return this; + } +} |