Skip to content

Commit 3cff591

Browse files
authored
Merge pull request #1672 from BillFarber/task/addNewSearchOptions
Can now use search options in ML12 for BM25, Zero, and Random.
2 parents 57e9764 + 183b016 commit 3cff591

File tree

5 files changed

+158
-32
lines changed

5 files changed

+158
-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: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,34 @@
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+
/**
24+
* Changed in release 6.7.0 to return a float, as the server requires a float and throws an error on a double.
25+
*/
26+
XsFloatVal getQualityWeight();
2627
ScoreMethod getScoreMethod();
27-
PlanSearchOptions withQualityWeight(double qualityWeight);
28-
PlanSearchOptions withQualityWeight(XsDoubleVal qualityWeight);
28+
/**
29+
* @since 6.7.0
30+
*/
31+
XsDoubleVal getBm25LengthWeight();
32+
/**
33+
* Changed in release 6.7.0 to return a float, as the server requires a float and throws an error on a double.
34+
*/
35+
PlanSearchOptions withQualityWeight(float qualityWeight);
36+
/**
37+
* Changed in release 6.7.0 to return a float, as the server requires a float and throws an error on a double.
38+
*/
39+
PlanSearchOptions withQualityWeight(XsFloatVal qualityWeight);
2940
PlanSearchOptions withScoreMethod(ScoreMethod scoreMethod);
41+
/**
42+
* @since 6.7.0
43+
*/
44+
PlanSearchOptions withBm25LengthWeight(double bm25LengthWeight);
3045
enum ScoreMethod {
31-
LOGTFIDF, LOGTF, SIMPLE;
46+
LOGTFIDF, LOGTF, SIMPLE, BM25, ZERO, RANDOM;
3247
}
3348
}
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)