ChlineSaurus commented on code in PR #3079:
URL: https://github.com/apache/jackrabbit-oak/pull/3079#discussion_r3810867323


##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticDynamicBoostTest.java:
##########
@@ -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.
+     */
+    @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"));
+        });
+    }
+

Review Comment:
   One thing an Agent flagged (and then verified via testing):
   
   It seems that the order can change when comparing the old vs new behavior. 
   Without grouping (as expected), the score is the sum of the matching values 
boosts divided by the number of matching values. With grouping, the boost still 
adds up all matching values, but the divider counts each boost-group only once 
instead of each value. So values sharing a group get summed on top yet divide 
only once.
   
   Example
   ```
     private static final String RED_BLUE_GREEN =
             "select [jcr:path] from [dam:Asset] where contains(*, 'red blue 
green')";
   
     private void createRankingAssets() throws Exception {
         createAssetsIndexAndProperties(false, false);
         Tree test = createNodeWithType(root.getTree("/"), "test", 
JcrConstants.NT_UNSTRUCTURED, "");
   
         // asset1: three tags sharing one boost group (boost 1)
         Tree many = createAssetNodeWithPredicted(test, "asset1", "titleone");
         createPredictedTag(many, "red", 1.0);
         createPredictedTag(many, "blue", 1.0);
         createPredictedTag(many, "green", 1.0);
   
         // asset2: one high-boost tag in its own group, the other two 
effectively zero
         Tree single = createAssetNodeWithPredicted(test, "asset2", "titletwo");
         createPredictedTag(single, "red", 4.0);
         createPredictedTag(single, "blue", 0.01);
         createPredictedTag(single, "green", 0.01);
     
         root.commit();
     }
   
     @Test
     public void rankingWithGroupingDisabled() throws Exception {
         // one nested doc per value: score_mode=avg divides by 3 children
         // -> asset2's single high boost (4) wins over asset1's three boost-1 
values
         ElasticDocument.FT_OAK_12353_ENABLE.set(false); // must be set before 
indexing (root.commit)
         createRankingAssets();
         assertEventually(() -> assertOrderedQuery(RED_BLUE_GREEN, 
List.of("/test/asset2", "/test/asset1")));
     }
     
     @Test
     public void rankingWithGroupingEnabled() throws Exception {
         // asset1's three boost-1 values collapse into ONE child; its text 
score sums the three
         // matched terms and score_mode=avg divides by 1 -> asset1 now 
outranks asset2. Order flips.
         ElasticDocument.FT_OAK_12353_ENABLE.set(true); // the OAK-12353 default
         createRankingAssets();
         assertEventually(() -> assertOrderedQuery(RED_BLUE_GREEN, 
List.of("/test/asset1", "/test/asset2")));
     }
   ```
   
   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. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to