-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Implement GRPC FunctionScoreQuery #19888
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
Merged
karenyrx
merged 13 commits into
opensearch-project:main
from
lucy66hw:0.23.0-functionscore
Nov 7, 2025
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
c1c58c0
Implement GRPC FunctionScoreQuery
lucy66hw 132c843
update changelog
lucy66hw 73f0498
spotlessApply
lucy66hw e3894c3
remove unused change
luckyxilu66 063d5dd
remove unused
luckyxilu66 149ec4b
Address comment
luckyxilu66 ac9a3de
rebase
lucy66hw 4cf7ccd
revert
lucy66hw 7fc8f8d
update changelog
lucy66hw f242543
rename converter to utils
lucy66hw 08af79e
revert removed tests
lucy66hw 499060b
spotlessApply
lucy66hw f979552
Merge branch 'main' into 0.23.0-functionscore
karenyrx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
...h/transport/grpc/proto/request/search/query/functionscore/ExpDecayFunctionProtoUtils.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| /* | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * The OpenSearch Contributors require contributions made to | ||
| * this file be licensed under the Apache-2.0 license or a | ||
| * compatible open source license. | ||
| */ | ||
| package org.opensearch.transport.grpc.proto.request.search.query.functionscore; | ||
|
|
||
| import org.opensearch.common.geo.GeoPoint; | ||
| import org.opensearch.index.query.functionscore.ExponentialDecayFunctionBuilder; | ||
| import org.opensearch.index.query.functionscore.ScoreFunctionBuilder; | ||
| import org.opensearch.protobufs.DateDecayPlacement; | ||
| import org.opensearch.protobufs.DecayFunction; | ||
| import org.opensearch.protobufs.DecayPlacement; | ||
| import org.opensearch.protobufs.GeoDecayPlacement; | ||
| import org.opensearch.protobufs.NumericDecayPlacement; | ||
| import org.opensearch.transport.grpc.proto.request.common.GeoPointProtoUtils; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Utility class for converting Protocol Buffer DecayFunction to OpenSearch ExponentialDecayFunctionBuilder. | ||
| * This utility handles the transformation of Protocol Buffer DecayFunction objects | ||
| * into OpenSearch ExponentialDecayFunctionBuilder instances. | ||
| */ | ||
| class ExpDecayFunctionProtoUtils { | ||
|
|
||
| private ExpDecayFunctionProtoUtils() { | ||
| // Utility class, no instances | ||
| } | ||
|
|
||
| /** | ||
| * Converts a Protocol Buffer DecayFunction to an OpenSearch ScoreFunctionBuilder. | ||
| * Similar to {@link org.opensearch.index.query.functionscore.DecayFunctionParser#fromXContent(org.opensearch.core.xcontent.XContentParser)}, | ||
| * this method parses the Protocol Buffer representation and creates a properly configured | ||
| * ExponentialDecayFunctionBuilder with decay placement parameters (numeric, geo, or date). | ||
| * | ||
| * @param decayFunction the Protocol Buffer DecayFunction | ||
| * @return the corresponding OpenSearch ScoreFunctionBuilder | ||
| * @throws IllegalArgumentException if the decayFunction is null or doesn't contain placements | ||
| */ | ||
| static ScoreFunctionBuilder<?> fromProto(DecayFunction decayFunction) { | ||
| if (decayFunction == null || decayFunction.getPlacementCount() == 0) { | ||
| throw new IllegalArgumentException("DecayFunction must have at least one placement"); | ||
| } | ||
|
|
||
| Map.Entry<String, DecayPlacement> entry = decayFunction.getPlacementMap().entrySet().iterator().next(); | ||
| String fieldName = entry.getKey(); | ||
| DecayPlacement decayPlacement = entry.getValue(); | ||
|
|
||
| if (decayPlacement.hasNumericDecayPlacement()) { | ||
| return parseNumericExpDecay(fieldName, decayPlacement.getNumericDecayPlacement()); | ||
| } else if (decayPlacement.hasGeoDecayPlacement()) { | ||
| return parseGeoExpDecay(fieldName, decayPlacement.getGeoDecayPlacement()); | ||
| } else if (decayPlacement.hasDateDecayPlacement()) { | ||
| return parseDateExpDecay(fieldName, decayPlacement.getDateDecayPlacement()); | ||
| } else { | ||
| throw new IllegalArgumentException("Unsupported decay placement type"); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Parses a numeric decay placement for exponential decay. | ||
| */ | ||
| private static ScoreFunctionBuilder<?> parseNumericExpDecay(String fieldName, NumericDecayPlacement numericPlacement) { | ||
| ExponentialDecayFunctionBuilder builder; | ||
| if (numericPlacement.hasDecay()) { | ||
| builder = new ExponentialDecayFunctionBuilder( | ||
| fieldName, | ||
| numericPlacement.getOrigin(), | ||
| numericPlacement.getScale(), | ||
| numericPlacement.hasOffset() ? numericPlacement.getOffset() : null, | ||
| numericPlacement.getDecay() | ||
| ); | ||
| } else { | ||
| builder = new ExponentialDecayFunctionBuilder( | ||
| fieldName, | ||
| numericPlacement.getOrigin(), | ||
| numericPlacement.getScale(), | ||
| numericPlacement.hasOffset() ? numericPlacement.getOffset() : null | ||
| ); | ||
| } | ||
|
|
||
| return builder; | ||
| } | ||
|
|
||
| /** | ||
| * Parses a geo decay placement for exponential decay. | ||
| */ | ||
| private static ScoreFunctionBuilder<?> parseGeoExpDecay(String fieldName, GeoDecayPlacement geoPlacement) { | ||
| GeoPoint geoPoint = GeoPointProtoUtils.parseGeoPoint(geoPlacement.getOrigin()); | ||
|
|
||
| ExponentialDecayFunctionBuilder builder; | ||
| if (geoPlacement.hasDecay()) { | ||
| builder = new ExponentialDecayFunctionBuilder( | ||
| fieldName, | ||
| geoPoint, | ||
| geoPlacement.getScale(), | ||
| geoPlacement.hasOffset() ? geoPlacement.getOffset() : null, | ||
| geoPlacement.getDecay() | ||
| ); | ||
| } else { | ||
| builder = new ExponentialDecayFunctionBuilder( | ||
| fieldName, | ||
| geoPoint, | ||
| geoPlacement.getScale(), | ||
| geoPlacement.hasOffset() ? geoPlacement.getOffset() : null | ||
| ); | ||
| } | ||
|
|
||
| return builder; | ||
| } | ||
|
|
||
| /** | ||
| * Parses a date decay placement for exponential decay. | ||
| */ | ||
| private static ScoreFunctionBuilder<?> parseDateExpDecay(String fieldName, DateDecayPlacement datePlacement) { | ||
| Object origin = datePlacement.hasOrigin() ? datePlacement.getOrigin() : null; | ||
|
|
||
| ExponentialDecayFunctionBuilder builder; | ||
| if (datePlacement.hasDecay()) { | ||
| builder = new ExponentialDecayFunctionBuilder( | ||
| fieldName, | ||
| origin, | ||
| datePlacement.getScale(), | ||
| datePlacement.hasOffset() ? datePlacement.getOffset() : null, | ||
| datePlacement.getDecay() | ||
| ); | ||
| } else { | ||
| builder = new ExponentialDecayFunctionBuilder( | ||
| fieldName, | ||
| origin, | ||
| datePlacement.getScale(), | ||
| datePlacement.hasOffset() ? datePlacement.getOffset() : null | ||
| ); | ||
| } | ||
|
|
||
| return builder; | ||
| } | ||
| } |
84 changes: 84 additions & 0 deletions
84
...ort/grpc/proto/request/search/query/functionscore/FieldValueFactorFunctionProtoUtils.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| /* | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * The OpenSearch Contributors require contributions made to | ||
| * this file be licensed under the Apache-2.0 license or a | ||
| * compatible open source license. | ||
| */ | ||
| package org.opensearch.transport.grpc.proto.request.search.query.functionscore; | ||
|
|
||
| import org.opensearch.index.query.functionscore.FieldValueFactorFunctionBuilder; | ||
| import org.opensearch.index.query.functionscore.ScoreFunctionBuilder; | ||
| import org.opensearch.protobufs.FieldValueFactorModifier; | ||
| import org.opensearch.protobufs.FieldValueFactorScoreFunction; | ||
|
|
||
| /** | ||
| * Utility class for converting Protocol Buffer FieldValueFactorScoreFunction to OpenSearch objects. | ||
| * This utility handles the transformation of Protocol Buffer FieldValueFactorScoreFunction objects | ||
| * into OpenSearch FieldValueFactorFunctionBuilder instances. | ||
| */ | ||
| class FieldValueFactorFunctionProtoUtils { | ||
|
|
||
| private FieldValueFactorFunctionProtoUtils() { | ||
| // Utility class, no instances | ||
| } | ||
|
|
||
| /** | ||
| * Converts a Protocol Buffer FieldValueFactorScoreFunction to an OpenSearch ScoreFunctionBuilder. | ||
| * Similar to {@link FieldValueFactorFunctionBuilder#fromXContent(XContentParser)}, this method | ||
| * parses the field, factor, missing value, and modifier parameters. | ||
| * | ||
| * @param fieldValueFactor the Protocol Buffer FieldValueFactorScoreFunction | ||
| * @return the corresponding OpenSearch ScoreFunctionBuilder | ||
| * @throws IllegalArgumentException if the fieldValueFactor is null | ||
| */ | ||
| static ScoreFunctionBuilder<?> fromProto(FieldValueFactorScoreFunction fieldValueFactor) { | ||
| if (fieldValueFactor == null) { | ||
| throw new IllegalArgumentException("FieldValueFactorScoreFunction cannot be null"); | ||
| } | ||
|
|
||
| FieldValueFactorFunctionBuilder builder = new FieldValueFactorFunctionBuilder(fieldValueFactor.getField()); | ||
|
|
||
| if (fieldValueFactor.hasFactor()) { | ||
| builder.factor(fieldValueFactor.getFactor()); | ||
| } | ||
|
|
||
| if (fieldValueFactor.hasMissing()) { | ||
| builder.missing(fieldValueFactor.getMissing()); | ||
| } | ||
|
|
||
| if (fieldValueFactor.getModifier() != FieldValueFactorModifier.FIELD_VALUE_FACTOR_MODIFIER_NONE) { | ||
| builder.modifier(parseFieldValueFactorModifier(fieldValueFactor.getModifier())); | ||
| } | ||
|
|
||
| return builder; | ||
| } | ||
|
|
||
| /** | ||
| * Parses a protobuf FieldValueFactorModifier and returns the corresponding OpenSearch modifier. | ||
| * | ||
| * @param modifier the protobuf FieldValueFactorModifier | ||
| * @return the corresponding OpenSearch FieldValueFactorFunction.Modifier | ||
| */ | ||
| private static org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier parseFieldValueFactorModifier( | ||
| FieldValueFactorModifier modifier | ||
| ) { | ||
| return switch (modifier) { | ||
| case FIELD_VALUE_FACTOR_MODIFIER_NONE -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.NONE; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_LOG -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.LOG; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_LOG1P -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.LOG1P; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_LOG2P -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.LOG2P; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_LN -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.LN; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_LN1P -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.LN1P; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_LN2P -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.LN2P; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_SQUARE -> | ||
| org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.SQUARE; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_SQRT -> org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.SQRT; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_RECIPROCAL -> | ||
| org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.RECIPROCAL; | ||
| case FIELD_VALUE_FACTOR_MODIFIER_UNSPECIFIED -> | ||
| org.opensearch.common.lucene.search.function.FieldValueFactorFunction.Modifier.NONE; | ||
| default -> throw new IllegalArgumentException("Unknown FieldValueFactorModifier: " + modifier); | ||
| }; | ||
| } | ||
| } |
47 changes: 47 additions & 0 deletions
47
...rpc/proto/request/search/query/functionscore/FunctionScoreQueryBuilderProtoConverter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /* | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * The OpenSearch Contributors require contributions made to | ||
| * this file be licensed under the Apache-2.0 license or a | ||
| * compatible open source license. | ||
| */ | ||
| package org.opensearch.transport.grpc.proto.request.search.query.functionscore; | ||
|
|
||
| import org.opensearch.index.query.QueryBuilder; | ||
| import org.opensearch.protobufs.QueryContainer; | ||
| import org.opensearch.transport.grpc.spi.QueryBuilderProtoConverter; | ||
| import org.opensearch.transport.grpc.spi.QueryBuilderProtoConverterRegistry; | ||
|
|
||
| /** | ||
| * Converter for FunctionScore queries. | ||
| * This class implements the QueryBuilderProtoConverter interface to provide FunctionScore query support | ||
| * for the gRPC transport module. | ||
| */ | ||
| public class FunctionScoreQueryBuilderProtoConverter implements QueryBuilderProtoConverter { | ||
|
|
||
| /** | ||
| * Default constructor for FunctionScoreQueryBuilderProtoConverter. | ||
| */ | ||
| public FunctionScoreQueryBuilderProtoConverter() {} | ||
|
|
||
| private QueryBuilderProtoConverterRegistry registry; | ||
|
|
||
| @Override | ||
| public void setRegistry(QueryBuilderProtoConverterRegistry registry) { | ||
| this.registry = registry; | ||
| } | ||
|
|
||
| @Override | ||
| public QueryContainer.QueryContainerCase getHandledQueryCase() { | ||
| return QueryContainer.QueryContainerCase.FUNCTION_SCORE; | ||
| } | ||
|
|
||
| @Override | ||
| public QueryBuilder fromProto(QueryContainer queryContainer) { | ||
| if (queryContainer == null || !queryContainer.hasFunctionScore()) { | ||
| throw new IllegalArgumentException("QueryContainer does not contain a FunctionScore query"); | ||
| } | ||
|
|
||
| return FunctionScoreQueryBuilderProtoUtils.fromProto(queryContainer.getFunctionScore(), registry); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.