Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
14c53c2
feat: add OpenSearch distance operations and selectors
mmiguerodriguez Sep 23, 2025
df6ffe6
Merge branch 'master' into feature/os-distance-operations
mmiguerodriguez Oct 2, 2025
a356951
feature: added new integration test
mmiguerodriguez Oct 7, 2025
9da8da8
Merge remote-tracking branch 'origin/master' into feature/os-distance…
mmiguerodriguez Oct 9, 2025
54f1eac
remove invalid assertions
mmiguerodriguez Oct 11, 2025
23b7b20
fix tests
mmiguerodriguez Oct 15, 2025
b529331
more test fixes...
mmiguerodriguez Oct 20, 2025
b461a0f
fix test by using default constructor
mmiguerodriguez Oct 22, 2025
bec8eb7
Merge branch 'master' into feature/os-distance-operations
mmiguerodriguez Oct 28, 2025
41fae1f
tests: add PR recommendations
mmiguerodriguez Nov 6, 2025
ae37f6a
Merge remote-tracking branch 'origin/master' into feature/os-distance…
mmiguerodriguez Nov 6, 2025
44452ff
Merge remote-tracking branch 'origin/master' into feature/os-distance…
mmiguerodriguez Nov 11, 2025
f47e055
Merge remote-tracking branch 'origin/master' into feature/os-distance…
mmiguerodriguez Nov 18, 2025
dfe913b
refactor: use if/else chain with warn log for unsupported ops
mmiguerodriguez Nov 18, 2025
5b7e4cd
fix: handle empty expectedTerms to prevent division by zero
mmiguerodriguez Nov 18, 2025
152a361
docs: clarify OpenSearch regex vs Java regex syntax differences
mmiguerodriguez Nov 18, 2025
b82ab2d
refactor: move generic string helpers to DistanceHelper
mmiguerodriguez Nov 18, 2025
7b612ad
fix: return 404 when no data found in age endpoints
mmiguerodriguez Nov 18, 2025
e17daa6
fix: return 404 in students endpoints and add 404 assertions in tests
mmiguerodriguez Nov 18, 2025
a874b55
fix: return 404 in queries endpoints and add 404 assertions
mmiguerodriguez Nov 18, 2025
51ab79a
refactor: move queries module to new folder structure
mmiguerodriguez Nov 18, 2025
4bf9147
style: remove redundant javadoc comments
mmiguerodriguez Nov 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions client-java/controller/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@
<scope>test</scope>
</dependency>

<!--OpenSearch test-->
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-java</artifactId>
<scope>test</scope>
</dependency>

<!--gRPC RPC test-->
<dependency>
<groupId>io.grpc</groupId>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,35 @@
import java.util.Objects;
import org.evomaster.client.java.controller.opensearch.operations.QueryOperation;
import org.evomaster.client.java.controller.opensearch.selectors.TermSelector;
import org.evomaster.client.java.controller.opensearch.selectors.TermsSelector;
import org.evomaster.client.java.controller.opensearch.selectors.TermsSetSelector;
import org.evomaster.client.java.controller.opensearch.selectors.IdsSelector;
import org.evomaster.client.java.controller.opensearch.selectors.RangeSelector;
import org.evomaster.client.java.controller.opensearch.selectors.PrefixSelector;
import org.evomaster.client.java.controller.opensearch.selectors.ExistsSelector;
import org.evomaster.client.java.controller.opensearch.selectors.FuzzySelector;
import org.evomaster.client.java.controller.opensearch.selectors.WildcardSelector;
import org.evomaster.client.java.controller.opensearch.selectors.RegexpSelector;
import org.evomaster.client.java.controller.opensearch.selectors.BoolSelector;
import org.evomaster.client.java.controller.opensearch.selectors.MatchSelector;
import org.evomaster.client.java.controller.opensearch.selectors.QuerySelector;

public class OpenSearchQueryParser {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need tests for OpenSearchQueryParser to check that the JSON is correctly parsed into its corresponding OpenSearch operation.


List<QuerySelector> selectors = Arrays.asList(new TermSelector());
List<QuerySelector> selectors = Arrays.asList(
new TermSelector(),
new TermsSelector(),
new TermsSetSelector(),
new IdsSelector(),
new RangeSelector(),
new PrefixSelector(),
new ExistsSelector(),
new FuzzySelector(),
new WildcardSelector(),
new RegexpSelector(),
new BoolSelector(),
new MatchSelector()
);

public QueryOperation parse(Object query) {
return selectors.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.evomaster.client.java.controller.opensearch.operations;

import java.util.List;

/**
* Represents Bool operation.
* A Boolean query can combine several query clauses into one advanced query. The clauses are combined
* with Boolean logic to find matching documents returned in the results.
* <p>
* <a href="https://docs.opensearch.org/latest/query-dsl/compound/bool/">OpenSearch Bool Operation</a>
*/
public class BoolOperation extends QueryOperation {
private final List<QueryOperation> must;
private final List<QueryOperation> mustNot;
private final List<QueryOperation> should;
private final List<QueryOperation> filter;
private final Integer minimumShouldMatch;
private final Float boost;

public BoolOperation(List<QueryOperation> must, List<QueryOperation> mustNot,
List<QueryOperation> should, List<QueryOperation> filter) {
this(must, mustNot, should, filter, null, null);
}

public BoolOperation(List<QueryOperation> must, List<QueryOperation> mustNot,
List<QueryOperation> should, List<QueryOperation> filter,
Integer minimumShouldMatch, Float boost) {
this.must = must;
this.mustNot = mustNot;
this.should = should;
this.filter = filter;
this.minimumShouldMatch = minimumShouldMatch;
this.boost = boost;
}

public List<QueryOperation> getMust() {
return must;
}

public List<QueryOperation> getMustNot() {
return mustNot;
}

public List<QueryOperation> getShould() {
return should;
}

public List<QueryOperation> getFilter() {
return filter;
}

public Integer getMinimumShouldMatch() {
return minimumShouldMatch;
}

public Float getBoost() {
return boost;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.evomaster.client.java.controller.opensearch.operations;

/**
* Common parameters shared across multiple OpenSearch query operations.
*/
public class CommonQueryParameters {
private final Float boost;
private final String name;
private final String rewrite;
private final Boolean caseInsensitive;

public CommonQueryParameters(Float boost, String name, String rewrite, Boolean caseInsensitive) {
this.boost = boost;
this.name = name;
this.rewrite = rewrite;
this.caseInsensitive = caseInsensitive;
}

public static CommonQueryParameters empty() {
return new CommonQueryParameters(null, null, null, null);
}

public static CommonQueryParameters withBoost(Float boost) {
return new CommonQueryParameters(boost, null, null, null);
}

public static CommonQueryParameters withCaseInsensitive(Boolean caseInsensitive) {
return new CommonQueryParameters(null, null, null, caseInsensitive);
}

public Float getBoost() {
return boost;
}

public String getName() {
return name;
}

public String getRewrite() {
return rewrite;
}

public Boolean getCaseInsensitive() {
return caseInsensitive;
}

public static class Builder {
private Float boost;
private String name;
private String rewrite;
private Boolean caseInsensitive;

public Builder boost(Float boost) {
this.boost = boost;
return this;
}

public Builder name(String name) {
this.name = name;
return this;
}

public Builder rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}

public Builder caseInsensitive(Boolean caseInsensitive) {
this.caseInsensitive = caseInsensitive;
return this;
}

public CommonQueryParameters build() {
return new CommonQueryParameters(boost, name, rewrite, caseInsensitive);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.evomaster.client.java.controller.opensearch.operations;

/**
* Represents Exists operation.
* Searches for documents that contain a specific field.
* <p>
* <a href="https://docs.opensearch.org/latest/query-dsl/term/exists/">OpenSearch Exists Operation</a>
*/
public class ExistsOperation extends QueryOperation {
private final String field;
private final Float boost;

public ExistsOperation(String field) {
this(field, null);
}

public ExistsOperation(String field, Float boost) {
this.field = field;
this.boost = boost;
}

public String getField() {
return field;
}

public Float getBoost() {
return boost;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.evomaster.client.java.controller.opensearch.operations;

/**
* Abstract base class for OpenSearch operations that operate on a specific field with a value.
* This includes operations like Term, Prefix, Wildcard, Fuzzy, and Regexp.
*/
public abstract class FieldValueOperation extends QueryOperation {
private final String fieldName;
private final String value;
private final CommonQueryParameters commonParams;

protected FieldValueOperation(String fieldName, String value, CommonQueryParameters commonParams) {
this.fieldName = fieldName;
this.value = value;
this.commonParams = commonParams != null ? commonParams : CommonQueryParameters.empty();
}

public String getFieldName() {
return fieldName;
}

public String getValue() {
return value;
}

public Float getBoost() {
return commonParams.getBoost();
}

public String getName() {
return commonParams.getName();
}

public String getRewrite() {
return commonParams.getRewrite();
}

public Boolean getCaseInsensitive() {
return commonParams.getCaseInsensitive();
}

protected CommonQueryParameters getCommonParams() {
return commonParams;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.evomaster.client.java.controller.opensearch.operations;

/**
* Represents Fuzzy operation.
* Searches for documents containing terms that are similar to the search term within the maximum allowed
* Damerau-Levenshtein distance. The Damerau-Levenshtein distance measures the number of one-character
* changes needed to change one term to another term.
* <p>
* <a href="https://docs.opensearch.org/latest/query-dsl/term/fuzzy/">OpenSearch Fuzzy Operation</a>
*/
public class FuzzyOperation extends QueryOperation {
private final String fieldName;
private final String value;
private final Float boost;
private final Integer fuzziness;
private final Integer maxExpansions;
private final Integer prefixLength;
private final Boolean transpositions;
private final String rewrite;

public FuzzyOperation(String fieldName, String value) {
this(fieldName, value, null, null, null, null, null, null);
}

public FuzzyOperation(String fieldName, String value, Float boost, Integer fuzziness,
Integer maxExpansions, Integer prefixLength, Boolean transpositions, String rewrite) {
this.fieldName = fieldName;
this.value = value;
this.boost = boost;
this.fuzziness = fuzziness;
this.maxExpansions = maxExpansions;
this.prefixLength = prefixLength;
this.transpositions = transpositions;
this.rewrite = rewrite;
}

public String getFieldName() {
return fieldName;
}

public String getValue() {
return value;
}

public Float getBoost() {
return boost;
}

public Integer getFuzziness() {
return fuzziness;
}

public Integer getMaxExpansions() {
return maxExpansions;
}

public Integer getPrefixLength() {
return prefixLength;
}

public Boolean getTranspositions() {
return transpositions;
}

public String getRewrite() {
return rewrite;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.evomaster.client.java.controller.opensearch.operations;

import java.util.List;

/**
* Represents IDs operation.
* Searches for documents with one or more specific document ID values in the _id field.
* <p>
* <a href="https://docs.opensearch.org/latest/query-dsl/term/ids/">OpenSearch IDs Operation</a>
*/
public class IdsOperation extends QueryOperation {
private final List<String> values;
private final Float boost;

public IdsOperation(List<String> values) {
this(values, null);
}

public IdsOperation(List<String> values, Float boost) {
this.values = values;
this.boost = boost;
}

public List<String> getValues() {
return values;
}

public Float getBoost() {
return boost;
}
}
Loading
Loading