Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Refactor the Cache.CacheStats class to use the Builder pattern instead of constructors ([#20015](https://github.com/opensearch-project/OpenSearch/pull/20015))
- Refactor the HttpStats, ScriptStats, AdaptiveSelectionStats and OsStats class to use the Builder pattern instead of constructors ([#20014](https://github.com/opensearch-project/OpenSearch/pull/20014))
- Bump opensearch-protobufs dependency to 0.24.0 and update transport-grpc module compatibility ([#20059](https://github.com/opensearch-project/OpenSearch/pull/20059))

- Refactor the ShardStats, WarmerStats and IndexingPressureStats class to use the Builder pattern instead of constructors ([#19966](https://github.com/opensearch-project/OpenSearch/pull/19966))
- Throw exceptions for currently unsupported GRPC request-side fields ([#20162](https://github.com/opensearch-project/OpenSearch/pull/20162))
- Add support for missing proto fields in GRPC FunctionScore and Highlight ([#20169](https://github.com/opensearch-project/OpenSearch/pull/20169))


### Fixed
- Fix Allocation and Rebalance Constraints of WeightFunction are incorrectly reset ([#19012](https://github.com/opensearch-project/OpenSearch/pull/19012))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ static HighlightBuilder fromProto(Highlight highlightProto, QueryBuilderProtoCon
highlightBuilder.encoder(ProtobufEnumUtils.convertToString(highlightProto.getEncoder()));
}

// TODO: Support useExplicitFieldOrder
// A spec fix is required and a corresponding protobuf version upgrade.

if (highlightProto.getFieldsCount() > 0) {
for (java.util.Map.Entry<String, org.opensearch.protobufs.HighlightField> entry : highlightProto.getFieldsMap().entrySet()) {
String fieldName = entry.getKey();
Expand Down Expand Up @@ -252,6 +255,22 @@ static HighlightBuilder fromProto(Highlight highlightProto, QueryBuilderProtoCon
fieldBuilder.forceSource(fieldProto.getForceSource());
}

if (fieldProto.hasOrder() && fieldProto.getOrder() == HighlighterOrder.HIGHLIGHTER_ORDER_SCORE) {
fieldBuilder.order(HighlightBuilder.Order.SCORE);
}

if (fieldProto.hasPhraseLimit()) {
fieldBuilder.phraseLimit(fieldProto.getPhraseLimit());
}

if (fieldProto.hasRequireFieldMatch()) {
fieldBuilder.requireFieldMatch(fieldProto.getRequireFieldMatch());
}

if (fieldProto.hasTagsSchema() && fieldProto.getTagsSchema() != HighlighterTagsSchema.HIGHLIGHTER_TAGS_SCHEMA_UNSPECIFIED) {
applyTagsSchemaToField(fieldBuilder, fieldProto.getTagsSchema());
}

highlightBuilder.field(fieldBuilder);
}
}
Expand All @@ -274,4 +293,28 @@ private static HighlightBuilder.BoundaryScannerType parseBoundaryScanner(Boundar
throw new IllegalArgumentException("Unknown BoundaryScanner value: " + boundaryScanner);
}
}

/**
* Apply tags schema to a highlight field by setting pre/post tags.
* This mirrors the behavior of {@link HighlightBuilder#tagsSchema(String)} but for field-level settings.
* <p>
* The {@code tagsSchema} method on {@link HighlightBuilder} sets built-in pre and post tags based on a schema name.
* Since {@link HighlightBuilder.Field} doesn't have a {@code tagsSchema} method, this helper applies the same
* logic by directly setting the pre/post tags on the field.
*
* @param fieldBuilder the highlight field builder to apply the tags schema to
* @param tagsSchema the tags schema to apply (e.g., STYLED)
* @see HighlightBuilder#tagsSchema(String)
*/
private static void applyTagsSchemaToField(HighlightBuilder.Field fieldBuilder, HighlighterTagsSchema tagsSchema) {
switch (tagsSchema) {
// TODO add HIGHLIGHTER_TAGS_SCHEMA_DEFAULT once new protobufs are published after spec fix
case HIGHLIGHTER_TAGS_SCHEMA_STYLED:
fieldBuilder.preTags(HighlightBuilder.DEFAULT_STYLED_PRE_TAG);
fieldBuilder.postTags(HighlightBuilder.DEFAULT_STYLED_POST_TAGS);
break;
default:
throw new IllegalArgumentException("Unknown tags schema: " + tagsSchema);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.protobufs.MultiValueMode;

/**
* Common utility class for decay function Protocol Buffer conversions.
* Contains shared methods used by {@link ExpDecayFunctionProtoUtils},
* {@link GaussDecayFunctionProtoUtils}, and {@link LinearDecayFunctionProtoUtils}.
*/
class DecayFunctionProtoUtils {

private DecayFunctionProtoUtils() {
// Utility class, no instances
}

/**
* Converts a Protocol Buffer MultiValueMode enum to OpenSearch MultiValueMode.
*
* @param multiValueMode the Protocol Buffer MultiValueMode enum value
* @return the corresponding OpenSearch MultiValueMode
* @throws IllegalArgumentException if the multiValueMode is unsupported
*/
static org.opensearch.search.MultiValueMode parseMultiValueMode(MultiValueMode multiValueMode) {
return switch (multiValueMode) {
case MULTI_VALUE_MODE_AVG -> org.opensearch.search.MultiValueMode.AVG;
case MULTI_VALUE_MODE_MAX -> org.opensearch.search.MultiValueMode.MAX;
case MULTI_VALUE_MODE_MIN -> org.opensearch.search.MultiValueMode.MIN;
case MULTI_VALUE_MODE_SUM -> org.opensearch.search.MultiValueMode.SUM;
default -> throw new IllegalArgumentException("Unsupported multi value mode: " + multiValueMode);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.opensearch.protobufs.DecayFunction;
import org.opensearch.protobufs.DecayPlacement;
import org.opensearch.protobufs.GeoDecayPlacement;
import org.opensearch.protobufs.MultiValueMode;
import org.opensearch.protobufs.NumericDecayPlacement;
import org.opensearch.transport.grpc.proto.request.common.GeoPointProtoUtils;

Expand Down Expand Up @@ -49,21 +50,29 @@ static ScoreFunctionBuilder<?> fromProto(DecayFunction decayFunction) {
String fieldName = entry.getKey();
DecayPlacement decayPlacement = entry.getValue();

ExponentialDecayFunctionBuilder builder;
if (decayPlacement.hasNumericDecayPlacement()) {
return parseNumericExpDecay(fieldName, decayPlacement.getNumericDecayPlacement());
builder = parseNumericExpDecay(fieldName, decayPlacement.getNumericDecayPlacement());
} else if (decayPlacement.hasGeoDecayPlacement()) {
return parseGeoExpDecay(fieldName, decayPlacement.getGeoDecayPlacement());
builder = parseGeoExpDecay(fieldName, decayPlacement.getGeoDecayPlacement());
} else if (decayPlacement.hasDateDecayPlacement()) {
return parseDateExpDecay(fieldName, decayPlacement.getDateDecayPlacement());
builder = parseDateExpDecay(fieldName, decayPlacement.getDateDecayPlacement());
} else {
throw new IllegalArgumentException("Unsupported decay placement type");
}

// Set multi_value_mode if present
if (decayFunction.hasMultiValueMode() && decayFunction.getMultiValueMode() != MultiValueMode.MULTI_VALUE_MODE_UNSPECIFIED) {
builder.setMultiValueMode(DecayFunctionProtoUtils.parseMultiValueMode(decayFunction.getMultiValueMode()));
}

return builder;
}

/**
* Parses a numeric decay placement for exponential decay.
*/
private static ScoreFunctionBuilder<?> parseNumericExpDecay(String fieldName, NumericDecayPlacement numericPlacement) {
private static ExponentialDecayFunctionBuilder parseNumericExpDecay(String fieldName, NumericDecayPlacement numericPlacement) {
ExponentialDecayFunctionBuilder builder;
if (numericPlacement.hasDecay()) {
builder = new ExponentialDecayFunctionBuilder(
Expand All @@ -88,7 +97,7 @@ private static ScoreFunctionBuilder<?> parseNumericExpDecay(String fieldName, Nu
/**
* Parses a geo decay placement for exponential decay.
*/
private static ScoreFunctionBuilder<?> parseGeoExpDecay(String fieldName, GeoDecayPlacement geoPlacement) {
private static ExponentialDecayFunctionBuilder parseGeoExpDecay(String fieldName, GeoDecayPlacement geoPlacement) {
GeoPoint geoPoint = GeoPointProtoUtils.parseGeoPoint(geoPlacement.getOrigin());

ExponentialDecayFunctionBuilder builder;
Expand All @@ -115,7 +124,7 @@ private static ScoreFunctionBuilder<?> parseGeoExpDecay(String fieldName, GeoDec
/**
* Parses a date decay placement for exponential decay.
*/
private static ScoreFunctionBuilder<?> parseDateExpDecay(String fieldName, DateDecayPlacement datePlacement) {
private static ExponentialDecayFunctionBuilder parseDateExpDecay(String fieldName, DateDecayPlacement datePlacement) {
Object origin = datePlacement.hasOrigin() ? datePlacement.getOrigin() : null;

ExponentialDecayFunctionBuilder builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.opensearch.protobufs.DecayFunction;
import org.opensearch.protobufs.DecayPlacement;
import org.opensearch.protobufs.GeoDecayPlacement;
import org.opensearch.protobufs.MultiValueMode;
import org.opensearch.protobufs.NumericDecayPlacement;
import org.opensearch.transport.grpc.proto.request.common.GeoPointProtoUtils;

Expand Down Expand Up @@ -49,21 +50,29 @@ static ScoreFunctionBuilder<?> fromProto(DecayFunction decayFunction) {
String fieldName = entry.getKey();
DecayPlacement decayPlacement = entry.getValue();

GaussDecayFunctionBuilder builder;
if (decayPlacement.hasNumericDecayPlacement()) {
return parseNumericGaussDecay(fieldName, decayPlacement.getNumericDecayPlacement());
builder = parseNumericGaussDecay(fieldName, decayPlacement.getNumericDecayPlacement());
} else if (decayPlacement.hasGeoDecayPlacement()) {
return parseGeoGaussDecay(fieldName, decayPlacement.getGeoDecayPlacement());
builder = parseGeoGaussDecay(fieldName, decayPlacement.getGeoDecayPlacement());
} else if (decayPlacement.hasDateDecayPlacement()) {
return parseDateGaussDecay(fieldName, decayPlacement.getDateDecayPlacement());
builder = parseDateGaussDecay(fieldName, decayPlacement.getDateDecayPlacement());
} else {
throw new IllegalArgumentException("Unsupported decay placement type");
}

// Set multi_value_mode if present
if (decayFunction.hasMultiValueMode() && decayFunction.getMultiValueMode() != MultiValueMode.MULTI_VALUE_MODE_UNSPECIFIED) {
builder.setMultiValueMode(DecayFunctionProtoUtils.parseMultiValueMode(decayFunction.getMultiValueMode()));
}

return builder;
}

/**
* Parses a numeric decay placement for Gaussian decay.
*/
private static ScoreFunctionBuilder<?> parseNumericGaussDecay(String fieldName, NumericDecayPlacement numericPlacement) {
private static GaussDecayFunctionBuilder parseNumericGaussDecay(String fieldName, NumericDecayPlacement numericPlacement) {
GaussDecayFunctionBuilder builder;
if (numericPlacement.hasDecay()) {
builder = new GaussDecayFunctionBuilder(
Expand All @@ -88,7 +97,7 @@ private static ScoreFunctionBuilder<?> parseNumericGaussDecay(String fieldName,
/**
* Parses a geo decay placement for Gaussian decay.
*/
private static ScoreFunctionBuilder<?> parseGeoGaussDecay(String fieldName, GeoDecayPlacement geoPlacement) {
private static GaussDecayFunctionBuilder parseGeoGaussDecay(String fieldName, GeoDecayPlacement geoPlacement) {
GeoPoint geoPoint = GeoPointProtoUtils.parseGeoPoint(geoPlacement.getOrigin());

GaussDecayFunctionBuilder builder;
Expand All @@ -115,7 +124,7 @@ private static ScoreFunctionBuilder<?> parseGeoGaussDecay(String fieldName, GeoD
/**
* Parses a date decay placement for Gaussian decay.
*/
private static ScoreFunctionBuilder<?> parseDateGaussDecay(String fieldName, DateDecayPlacement datePlacement) {
private static GaussDecayFunctionBuilder parseDateGaussDecay(String fieldName, DateDecayPlacement datePlacement) {
Object origin = datePlacement.hasOrigin() ? datePlacement.getOrigin() : null;

GaussDecayFunctionBuilder builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.opensearch.protobufs.DecayFunction;
import org.opensearch.protobufs.DecayPlacement;
import org.opensearch.protobufs.GeoDecayPlacement;
import org.opensearch.protobufs.MultiValueMode;
import org.opensearch.protobufs.NumericDecayPlacement;
import org.opensearch.transport.grpc.proto.request.common.GeoPointProtoUtils;

Expand Down Expand Up @@ -49,15 +50,23 @@ static ScoreFunctionBuilder<?> fromProto(DecayFunction decayFunction) {
String fieldName = entry.getKey();
DecayPlacement decayPlacement = entry.getValue();

LinearDecayFunctionBuilder builder;
if (decayPlacement.hasNumericDecayPlacement()) {
return parseNumericLinearDecay(fieldName, decayPlacement.getNumericDecayPlacement());
builder = parseNumericLinearDecay(fieldName, decayPlacement.getNumericDecayPlacement());
} else if (decayPlacement.hasGeoDecayPlacement()) {
return parseGeoLinearDecay(fieldName, decayPlacement.getGeoDecayPlacement());
builder = parseGeoLinearDecay(fieldName, decayPlacement.getGeoDecayPlacement());
} else if (decayPlacement.hasDateDecayPlacement()) {
return parseDateLinearDecay(fieldName, decayPlacement.getDateDecayPlacement());
builder = parseDateLinearDecay(fieldName, decayPlacement.getDateDecayPlacement());
} else {
throw new IllegalArgumentException("Unsupported decay placement type");
}

// Set multi_value_mode if present
if (decayFunction.hasMultiValueMode() && decayFunction.getMultiValueMode() != MultiValueMode.MULTI_VALUE_MODE_UNSPECIFIED) {
builder.setMultiValueMode(DecayFunctionProtoUtils.parseMultiValueMode(decayFunction.getMultiValueMode()));
}

return builder;
}

/**
Expand All @@ -69,7 +78,7 @@ static ScoreFunctionBuilder<?> fromProto(DecayFunction decayFunction) {
* @param numericPlacement the protobuf numeric decay placement containing origin, scale, offset, and decay
* @return the corresponding OpenSearch LinearDecayFunctionBuilder
*/
private static ScoreFunctionBuilder<?> parseNumericLinearDecay(String fieldName, NumericDecayPlacement numericPlacement) {
private static LinearDecayFunctionBuilder parseNumericLinearDecay(String fieldName, NumericDecayPlacement numericPlacement) {
LinearDecayFunctionBuilder builder;
if (numericPlacement.hasDecay()) {
builder = new LinearDecayFunctionBuilder(
Expand Down Expand Up @@ -100,7 +109,7 @@ private static ScoreFunctionBuilder<?> parseNumericLinearDecay(String fieldName,
* @param geoPlacement the protobuf geo decay placement containing origin (lat/lon), scale, offset, and decay
* @return the corresponding OpenSearch LinearDecayFunctionBuilder
*/
private static ScoreFunctionBuilder<?> parseGeoLinearDecay(String fieldName, GeoDecayPlacement geoPlacement) {
private static LinearDecayFunctionBuilder parseGeoLinearDecay(String fieldName, GeoDecayPlacement geoPlacement) {
GeoPoint geoPoint = GeoPointProtoUtils.parseGeoPoint(geoPlacement.getOrigin());

LinearDecayFunctionBuilder builder;
Expand Down Expand Up @@ -133,7 +142,7 @@ private static ScoreFunctionBuilder<?> parseGeoLinearDecay(String fieldName, Geo
* @param datePlacement the protobuf date decay placement containing origin (date), scale, offset, and decay
* @return the corresponding OpenSearch LinearDecayFunctionBuilder
*/
private static ScoreFunctionBuilder<?> parseDateLinearDecay(String fieldName, DateDecayPlacement datePlacement) {
private static LinearDecayFunctionBuilder parseDateLinearDecay(String fieldName, DateDecayPlacement datePlacement) {
Object origin = datePlacement.hasOrigin() ? datePlacement.getOrigin() : null;

LinearDecayFunctionBuilder builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ static ScoreFunctionBuilder<?> fromProto(RandomScoreFunction randomScore) {
org.opensearch.protobufs.RandomScoreFunctionSeed seed = randomScore.getSeed();
if (seed.hasInt32()) {
builder.seed(seed.getInt32());
} else if (seed.hasInt64()) {
builder.seed(seed.getInt64());
} else if (seed.hasString()) {
builder.seed(seed.getString());
}
Expand Down
Loading
Loading