-
Notifications
You must be signed in to change notification settings - Fork 427
OAK-12353: Group Elasticsearch dynamic boost nested documents by boost score #3079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
cc5efe7
e28a7ee
36939dd
54f935a
110ad7f
4225ea9
9e365f7
375b9fa
68511d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,8 @@ | |
| import org.apache.jackrabbit.oak.api.ContentRepository; | ||
| import org.apache.jackrabbit.oak.api.Tree; | ||
| import org.apache.jackrabbit.oak.plugins.index.DynamicBoostCommonTest; | ||
| import org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticDocument; | ||
| import org.junit.After; | ||
| import org.junit.ClassRule; | ||
| import org.junit.Test; | ||
|
|
||
|
|
@@ -85,6 +87,63 @@ public void dynamicBoostAnalyzed() throws Exception { | |
| }); | ||
| } | ||
|
|
||
| @After | ||
| public void resetDynamicBoostGroupingToggle() { | ||
| ElasticDocument.FT_OAK_12353_ENABLE.set(true); | ||
| } | ||
|
|
||
| /** | ||
| * Predicted tags sharing the same boost score are grouped into a single nested document | ||
| * (see {@link ElasticDocument#FT_OAK_12353_ENABLE}). This verifies that querying still | ||
| * matches on any of the grouped values, both with the grouping enabled (default) and | ||
| * disabled. | ||
| */ | ||
|
Comment on lines
+95
to
+100
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see how the test below (which asserts on query results) "proves" that the different tags are found within the same nested document. Maybe I missed something ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I got confused by the first phrase of the comment. Thought it was a statement. Maybe rephrase ? "Verify that querying give the same results whether grouping by boost (see ...) is active or not.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would even try to write the test in such a way that the body of the test with and without the toggle is shared making it straight forward. |
||
| @Test | ||
| public void dynamicBoostQueriesGroupedValuesSharingSameBoostScore() throws Exception { | ||
| createAssetsIndexAndProperties(false, false); | ||
|
|
||
| Tree testParent = createNodeWithType(root.getTree("/"), "test", JcrConstants.NT_UNSTRUCTURED, ""); | ||
|
|
||
| Tree predicted1 = createAssetNodeWithPredicted(testParent, "asset1", "flower with a lot of red and a bit of blue"); | ||
| createPredictedTag(predicted1, "red", 5.0); | ||
| createPredictedTag(predicted1, "blue", 5.0); | ||
| createPredictedTag(predicted1, "green", 5.0); | ||
| createPredictedTag(predicted1, "special", 9.0); | ||
|
|
||
| root.commit(); | ||
|
|
||
| assertEventually(() -> { | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'red')]", XPATH, List.of("/test/asset1")); | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'blue')]", XPATH, List.of("/test/asset1")); | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'green')]", XPATH, List.of("/test/asset1")); | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'special')]", XPATH, List.of("/test/asset1")); | ||
| }); | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing an Agent flagged (and then verified via testing): It seems that the order can change when comparing the old vs new behavior. Example I'm not sure if this is a problem, but I thought it was still worth mentioning, especially as in my understanding we will have a mixed behavior for some time. |
||
| @Test | ||
| public void dynamicBoostQueriesValuesSharingSameBoostScoreWhenGroupingDisabled() throws Exception { | ||
| ElasticDocument.FT_OAK_12353_ENABLE.set(false); | ||
|
|
||
| createAssetsIndexAndProperties(false, false); | ||
|
|
||
| Tree testParent = createNodeWithType(root.getTree("/"), "test", JcrConstants.NT_UNSTRUCTURED, ""); | ||
|
|
||
| Tree predicted1 = createAssetNodeWithPredicted(testParent, "asset1", "flower with a lot of red and a bit of blue"); | ||
| createPredictedTag(predicted1, "red", 5.0); | ||
| createPredictedTag(predicted1, "blue", 5.0); | ||
| createPredictedTag(predicted1, "green", 5.0); | ||
| createPredictedTag(predicted1, "special", 9.0); | ||
|
|
||
| root.commit(); | ||
|
|
||
| assertEventually(() -> { | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'red')]", XPATH, List.of("/test/asset1")); | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'blue')]", XPATH, List.of("/test/asset1")); | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'green')]", XPATH, List.of("/test/asset1")); | ||
| assertQuery("//element(*, dam:Asset)[jcr:contains(., 'special')]", XPATH, List.of("/test/asset1")); | ||
| }); | ||
| } | ||
|
|
||
| @Test | ||
| public void dynamicBoostNotIncludedInFullText() throws Exception { | ||
| createAssetsIndexAndProperties(false, false, false); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| /* | ||
| * 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.jackrabbit.oak.plugins.index.elastic.index; | ||
|
|
||
| import org.junit.After; | ||
| import org.junit.Test; | ||
|
|
||
| import java.time.LocalDate; | ||
| import java.util.ArrayList; | ||
| import java.util.Collection; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import static org.junit.Assert.assertEquals; | ||
| import static org.junit.Assert.assertTrue; | ||
|
|
||
| public class ElasticDocumentTest { | ||
|
|
||
| @After | ||
| public void resetToggle() { | ||
| ElasticDocument.FT_OAK_12353_ENABLE.set(true); | ||
| } | ||
|
|
||
| @Test | ||
| public void dynamicBoostValuesAreNotGroupedWhenToggleDisabled() { | ||
| ElasticDocument.FT_OAK_12353_ENABLE.set(false); | ||
|
|
||
| ElasticDocument doc = new ElasticDocument("/test"); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "Replacement Cost", 1.0); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "Theft", 1.0); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "GENERAL INSURANCE COMPANY", 0.988); | ||
|
|
||
| Object value = doc.getProperties().get("predictedTagsDynamicBoost"); | ||
| assertTrue(value instanceof Set); | ||
| @SuppressWarnings("unchecked") | ||
| Set<Map<String, Object>> nestedDocs = (Set<Map<String, Object>>) value; | ||
| assertEquals(3, nestedDocs.size()); | ||
| for (Map<String, Object> nestedDoc : nestedDocs) { | ||
| assertTrue(nestedDoc.get(ElasticIndexHelper.DYNAMIC_BOOST_NESTED_VALUE) instanceof String); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void dynamicBoostValuesAreGroupedByBoostByDefault() { | ||
| ElasticDocument doc = new ElasticDocument("/test"); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "Replacement Cost", 1.0); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "Theft", 1.0); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "Alberta", 1.0); | ||
| doc.addDynamicBoostField("predictedTagsDynamicBoost", "GENERAL INSURANCE COMPANY", 0.988); | ||
|
|
||
| Object value = doc.getProperties().get("predictedTagsDynamicBoost"); | ||
| assertTrue(value instanceof Set); | ||
| @SuppressWarnings("unchecked") | ||
| Set<Map<String, Object>> nestedDocs = (Set<Map<String, Object>>) value; | ||
| // one nested doc for the 3 values sharing boost=1.0, one for the distinct boost=0.988 | ||
| assertEquals(2, nestedDocs.size()); | ||
|
|
||
| boolean foundGrouped = false; | ||
| boolean foundSingle = false; | ||
| for (Map<String, Object> nestedDoc : nestedDocs) { | ||
| Object boost = nestedDoc.get(ElasticIndexHelper.DYNAMIC_BOOST_NESTED_BOOST); | ||
| Object nestedValue = nestedDoc.get(ElasticIndexHelper.DYNAMIC_BOOST_NESTED_VALUE); | ||
| if (Double.valueOf(1.0).equals(boost)) { | ||
| assertTrue(nestedValue instanceof Collection); | ||
| @SuppressWarnings("unchecked") | ||
| Collection<String> values = (Collection<String>) nestedValue; | ||
| assertEquals(List.of("Replacement Cost", "Theft", "Alberta"), new ArrayList<>(values)); | ||
| foundGrouped = true; | ||
| } else if (Double.valueOf(0.988).equals(boost)) { | ||
| assertEquals("GENERAL INSURANCE COMPANY", nestedValue); | ||
| foundSingle = true; | ||
| } | ||
| } | ||
| assertTrue(foundGrouped); | ||
| assertTrue(foundSingle); | ||
| } | ||
|
|
||
| @Test | ||
| public void ft_oak_12353_toggleShouldBeRemoved() { | ||
| // Time-bombed: if this test fails, the feature toggle FT_OAK-12353 and its guard in | ||
| // ElasticDocument#addDynamicBoostField/#getProperties should be removed — the grouping | ||
| // has been enabled by default in production long enough. | ||
| assertTrue("Feature toggle " + ElasticDocument.FT_OAK_12353 + " is overdue for removal", | ||
| LocalDate.now().isBefore(LocalDate.of(2027, 8, 12))); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. So the field length of multi-valued fields is the sum of the lengths of the values ? It varied as well before no ? (Just a curiosity)