Skip to content

Commit 907bf43

Browse files
committed
Can now use search options in ML12 for BM25, Zero, and Random.
Also adds a setting for BM25 Length Weight. Added a couple of tests. These tests are of limited use here, but they do verify that "bm25" and "zero" are acceptable scoring options. They also verify the exception when bm25lengthweight is out of bounds.
1 parent 57e9764 commit 907bf43

File tree

5 files changed

+143
-32
lines changed

5 files changed

+143
-32
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/impl/PlanBuilderBaseImpl.java

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -61,49 +61,65 @@ public PlanSearchOptions searchOptions() {
6161

6262
static class PlanSearchOptionsImpl implements PlanSearchOptions {
6363
private PlanBuilderBaseImpl pb;
64-
private XsDoubleVal qualityWeight;
64+
private XsFloatVal qualityWeight;
6565
private ScoreMethod scoreMethod;
66+
private XsDoubleVal bm25LengthWeight;
6667
PlanSearchOptionsImpl(PlanBuilderBaseImpl pb) {
6768
this.pb = pb;
6869
}
69-
PlanSearchOptionsImpl(PlanBuilderBaseImpl pb, XsDoubleVal qualityWeight, ScoreMethod scoreMethod) {
70-
this(pb);
71-
this.qualityWeight = qualityWeight;
72-
this.scoreMethod = scoreMethod;
73-
}
70+
PlanSearchOptionsImpl(PlanBuilderBaseImpl pb, XsFloatVal qualityWeight,
71+
ScoreMethod scoreMethod, XsDoubleVal bm25LengthWeight) {
72+
this(pb);
73+
this.qualityWeight = qualityWeight;
74+
this.scoreMethod = scoreMethod;
75+
this.bm25LengthWeight = bm25LengthWeight;
76+
}
7477

7578
@Override
76-
public XsDoubleVal getQualityWeight() {
79+
public XsFloatVal getQualityWeight() {
7780
return qualityWeight;
7881
}
7982
@Override
8083
public ScoreMethod getScoreMethod() {
8184
return scoreMethod;
8285
}
86+
@Override
87+
public XsDoubleVal getBm25LengthWeight() {
88+
return bm25LengthWeight;
89+
}
8390
@Override
84-
public PlanSearchOptions withQualityWeight(double qualityWeight) {
85-
return withQualityWeight(pb.xs.doubleVal(qualityWeight));
91+
public PlanSearchOptions withQualityWeight(float qualityWeight) {
92+
return withQualityWeight(pb.xs.floatVal(qualityWeight));
8693
}
8794
@Override
88-
public PlanSearchOptions withQualityWeight(XsDoubleVal qualityWeight) {
89-
return new PlanSearchOptionsImpl(pb, qualityWeight, getScoreMethod());
95+
public PlanSearchOptions withQualityWeight(XsFloatVal qualityWeight) {
96+
return new PlanSearchOptionsImpl(pb, qualityWeight, getScoreMethod(), getBm25LengthWeight());
9097
}
9198
@Override
9299
public PlanSearchOptions withScoreMethod(ScoreMethod scoreMethod) {
93-
return new PlanSearchOptionsImpl(pb, getQualityWeight(), scoreMethod);
94-
}
95-
Map<String,String> makeMap() {
96-
if (qualityWeight == null && scoreMethod == null) return null;
97-
98-
Map<String, String> map = new HashMap<String, String>();
99-
if (qualityWeight != null) {
100-
map.put("qualityWeight", String.valueOf(qualityWeight));
101-
}
102-
if (scoreMethod != null) {
103-
map.put("scoreMethod", scoreMethod.name().toLowerCase());
104-
}
105-
return map;
106-
}
100+
return new PlanSearchOptionsImpl(pb, getQualityWeight(), scoreMethod, getBm25LengthWeight());
101+
}
102+
103+
@Override
104+
public PlanSearchOptions withBm25LengthWeight(double bm25LengthWeight) {
105+
return new PlanSearchOptionsImpl(pb, getQualityWeight(), getScoreMethod(), pb.xs.doubleVal(bm25LengthWeight));
106+
}
107+
108+
Map<String,Object> makeMap() {
109+
if (qualityWeight == null && scoreMethod == null && bm25LengthWeight == null) return null;
110+
111+
Map<String, Object> map = new HashMap<>();
112+
if (qualityWeight != null) {
113+
map.put("qualityWeight", qualityWeight);
114+
}
115+
if (scoreMethod != null) {
116+
map.put("scoreMethod", scoreMethod.name().toLowerCase());
117+
}
118+
if (bm25LengthWeight != null) {
119+
map.put("bm25LengthWeight", bm25LengthWeight);
120+
}
121+
return map;
122+
}
107123
}
108124

109125
static class PlanParamBase extends BaseTypeImpl.BaseCallImpl<XsValueImpl.StringValImpl> implements PlanParamExpr {

marklogic-client-api/src/main/java/com/marklogic/client/impl/PlanBuilderSubImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ static class ParamCallImpl extends PlanCallImpl implements PlanParamExpr {
675675
}
676676
}
677677

678-
static Map<String,String> makeMap(PlanSearchOptions options) {
678+
static Map<String,Object> makeMap(PlanSearchOptions options) {
679679
if (options == null) {
680680
return null;
681681
}

marklogic-client-api/src/main/java/com/marklogic/client/type/PlanSearchOptions.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@
1515
*/
1616
package com.marklogic.client.type;
1717

18-
// IMPORTANT: Do not edit. This file is generated.
19-
2018
/**
2119
* An option controlling the scoring and weighting of fromSearch()
2220
* for a row pipeline.
2321
*/
2422
public interface PlanSearchOptions {
25-
XsDoubleVal getQualityWeight();
23+
XsFloatVal getQualityWeight();
2624
ScoreMethod getScoreMethod();
27-
PlanSearchOptions withQualityWeight(double qualityWeight);
28-
PlanSearchOptions withQualityWeight(XsDoubleVal qualityWeight);
25+
XsDoubleVal getBm25LengthWeight();
26+
PlanSearchOptions withQualityWeight(float qualityWeight);
27+
PlanSearchOptions withQualityWeight(XsFloatVal qualityWeight);
2928
PlanSearchOptions withScoreMethod(ScoreMethod scoreMethod);
29+
PlanSearchOptions withBm25LengthWeight(double bm25LengthWeight);
3030
enum ScoreMethod {
31-
LOGTFIDF, LOGTF, SIMPLE;
31+
LOGTFIDF, LOGTF, SIMPLE, BM25, ZERO, RANDOM;
3232
}
3333
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.marklogic.client.test.junit5;
2+
3+
import com.marklogic.client.test.Common;
4+
import com.marklogic.client.test.MarkLogicVersion;
5+
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
6+
import org.junit.jupiter.api.extension.ExecutionCondition;
7+
import org.junit.jupiter.api.extension.ExtensionContext;
8+
9+
public class RequiresML12 implements ExecutionCondition {
10+
11+
private static MarkLogicVersion markLogicVersion;
12+
13+
@Override
14+
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
15+
if (markLogicVersion == null) {
16+
markLogicVersion = Common.getMarkLogicVersion();
17+
}
18+
return markLogicVersion.getMajor() >= 12 ?
19+
ConditionEvaluationResult.enabled("MarkLogic is version 12 or higher") :
20+
ConditionEvaluationResult.disabled("MarkLogic is version 11 or lower");
21+
}
22+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.marklogic.client.test.rows;
2+
3+
import com.marklogic.client.FailedRequestException;
4+
import com.marklogic.client.expression.PlanBuilder;
5+
import com.marklogic.client.row.RowRecord;
6+
import com.marklogic.client.test.junit5.RequiresML12;
7+
import com.marklogic.client.type.PlanSearchOptions;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.extension.ExtendWith;
10+
11+
import java.util.List;
12+
13+
import static org.junit.jupiter.api.Assertions.*;
14+
15+
@ExtendWith(RequiresML12.class)
16+
class FromSearchWithOptionsTest extends AbstractOpticUpdateTest {
17+
18+
@Test
19+
void bm25() {
20+
// Note that this does not actually test that the scoring is correct.
21+
// It only tests that including the BM25 scoring option and a valid bm25LengthWeight do not cause any problems.
22+
rowManager.withUpdate(false);
23+
PlanSearchOptions options = op.searchOptions()
24+
.withScoreMethod(PlanSearchOptions.ScoreMethod.BM25)
25+
.withBm25LengthWeight(0.25);
26+
List<RowRecord> rows = resultRows(
27+
op.fromSearch(op.cts.wordQuery("contents"), null, null, options)
28+
.offsetLimit(0, 5)
29+
);
30+
assertEquals(5, rows.size());
31+
}
32+
33+
@Test
34+
void badBm25LengthWeight() {
35+
rowManager.withUpdate(false);
36+
PlanSearchOptions options = op.searchOptions()
37+
.withScoreMethod(PlanSearchOptions.ScoreMethod.BM25)
38+
.withBm25LengthWeight(99);
39+
PlanBuilder.ModifyPlan plan = op.fromSearch(op.cts.wordQuery("contents"), null, null, options)
40+
.offsetLimit(0, 5);
41+
Exception exception = assertThrows(FailedRequestException.class, () -> resultRows(plan));
42+
String actualMessage = exception.getMessage();
43+
assertTrue(actualMessage.contains("Server Message: XDMP-OPTION"));
44+
assertTrue(actualMessage.contains("Invalid option \"bm25-length-weight"));
45+
}
46+
47+
@Test
48+
void zero() {
49+
rowManager.withUpdate(false);
50+
PlanSearchOptions options = op.searchOptions().withScoreMethod(PlanSearchOptions.ScoreMethod.ZERO);
51+
List<RowRecord> rows = resultRows(
52+
op.fromSearch(op.cts.wordQuery("contents"), null, null, options)
53+
.offsetLimit(0, 5)
54+
);
55+
assertEquals(5, rows.size());
56+
rows.forEach(row -> {
57+
assertEquals(0, row.getInt("score"), "The score for every row should be 0.");
58+
});
59+
}
60+
61+
@Test
62+
void qualityWeight() {
63+
// Note that this does not actually test that the scoring is correct.
64+
// It only tests that including a valid qualityWeight value does not cause any problems.
65+
rowManager.withUpdate(false);
66+
PlanSearchOptions options = op.searchOptions().withScoreMethod(PlanSearchOptions.ScoreMethod.LOGTFIDF).withQualityWeight(0.75F);
67+
List<RowRecord> rows = resultRows(
68+
op.fromSearch(op.cts.wordQuery("contents"), null, null, options)
69+
.offsetLimit(0, 5)
70+
);
71+
assertEquals(5, rows.size());
72+
}
73+
}

0 commit comments

Comments
 (0)