@@ -89,12 +89,35 @@ public final class RRFRetrieverBuilder extends CompoundRetrieverBuilder<RRFRetri
8989
9090 static {
9191 PARSER .declareObjectArray (ConstructingObjectParser .optionalConstructorArg (), RRFRetrieverComponent ::fromXContent , RETRIEVERS_FIELD );
92- PARSER .declareField (
93- ConstructingObjectParser .optionalConstructorArg (),
94- RRFRetrieverBuilder ::parseFieldsArray ,
95- FIELDS_FIELD ,
96- ObjectParser .ValueType .VALUE_ARRAY
97- );
92+ PARSER .declareField (ConstructingObjectParser .optionalConstructorArg (), (p , c ) -> {
93+ List <String > fields = new ArrayList <>();
94+ XContentParser .Token token = p .currentToken ();
95+ if (token == XContentParser .Token .START_ARRAY ) {
96+ while ((token = p .nextToken ()) != XContentParser .Token .END_ARRAY ) {
97+ if (token == XContentParser .Token .VALUE_STRING ) {
98+ fields .add (p .text ());
99+ } else if (token == XContentParser .Token .START_OBJECT ) {
100+ String fieldName = null ;
101+ float weight = 1.0f ;
102+ while (p .nextToken () != XContentParser .Token .END_OBJECT ) {
103+ if (p .currentToken () == XContentParser .Token .FIELD_NAME ) {
104+ String name = p .currentName ();
105+ p .nextToken ();
106+ if ("field" .equals (name )) {
107+ fieldName = p .text ();
108+ } else if ("weight" .equals (name )) {
109+ weight = p .floatValue ();
110+ }
111+ }
112+ }
113+ if (fieldName != null ) {
114+ fields .add (weight == 1.0f ? fieldName : fieldName + "^" + weight );
115+ }
116+ }
117+ }
118+ }
119+ return fields ;
120+ }, FIELDS_FIELD , ObjectParser .ValueType .VALUE_ARRAY );
98121 PARSER .declareString (ConstructingObjectParser .optionalConstructorArg (), QUERY_FIELD );
99122 PARSER .declareInt (ConstructingObjectParser .optionalConstructorArg (), RANK_WINDOW_SIZE_FIELD );
100123 PARSER .declareInt (ConstructingObjectParser .optionalConstructorArg (), RANK_CONSTANT_FIELD );
@@ -108,59 +131,6 @@ public static RRFRetrieverBuilder fromXContent(XContentParser parser, RetrieverP
108131 return PARSER .apply (parser , context );
109132 }
110133
111- private static List <String > parseFieldsArray (XContentParser parser , Object context ) throws IOException {
112- List <String > fields = new ArrayList <>();
113- XContentParser .Token token = parser .currentToken ();
114-
115- // Handle both cases: when parser is at START_ARRAY and when it's already in the array
116- if (token == XContentParser .Token .START_ARRAY ) {
117- token = parser .nextToken ();
118- }
119-
120- while (token != XContentParser .Token .END_ARRAY ) {
121- if (token == XContentParser .Token .VALUE_STRING ) {
122- // Handle string format: "field^weight" or "field"
123- fields .add (parser .text ());
124- } else if (token == XContentParser .Token .START_OBJECT ) {
125- // Handle object format: {"field": "field_name", "weight": 2.0}
126- String fieldName = null ;
127- float weight = 1.0f ;
128-
129- while ((token = parser .nextToken ()) != XContentParser .Token .END_OBJECT ) {
130- if (token == XContentParser .Token .FIELD_NAME ) {
131- String currentName = parser .currentName ();
132- token = parser .nextToken ();
133-
134- if ("field" .equals (currentName )) {
135- fieldName = parser .text ();
136- } else if ("weight" .equals (currentName )) {
137- weight = parser .floatValue ();
138- } else {
139- throw new IllegalArgumentException ("Unknown field in field object: " + currentName );
140- }
141- }
142- }
143-
144- if (fieldName == null ) {
145- throw new IllegalArgumentException ("Missing 'field' property in field object" );
146- }
147-
148- // Convert to string format: "field^weight"
149- if (weight == 1.0f ) {
150- fields .add (fieldName );
151- } else {
152- fields .add (fieldName + "^" + weight );
153- }
154- } else {
155- throw new IllegalArgumentException ("Expected string or object in fields array, but found: " + token );
156- }
157-
158- token = parser .nextToken ();
159- }
160-
161- return fields ;
162- }
163-
164134 private final List <String > fields ;
165135 private final String query ;
166136 private final int rankConstant ;
@@ -190,15 +160,10 @@ public RRFRetrieverBuilder(
190160 this .query = query ;
191161 this .rankConstant = rankConstant ;
192162 Objects .requireNonNull (weights , "weights must not be null" );
193- // For simplified syntax (fields + query), allow empty weights array since weights are handled during rewrite
194- // For explicit retriever syntax, weights must match the number of retrievers
195- if (fields == null || query == null ) {
196- // Explicit retriever syntax - validate weights match retrievers
197- if (weights .length != innerRetrievers .size ()) {
198- throw new IllegalArgumentException (
199- "weights array length [" + weights .length + "] must match retrievers count [" + innerRetrievers .size () + "]"
200- );
201- }
163+ if (weights .length != innerRetrievers .size ()) {
164+ throw new IllegalArgumentException (
165+ "weights array length [" + weights .length + "] must match retrievers count [" + innerRetrievers .size () + "]"
166+ );
202167 }
203168 this .weights = weights ;
204169 }
0 commit comments