Handling Repeatable Fields With Free Entry Text
Summary
Currently, a repeatable field yields a match only when the search term fully corresponds to one of its values. This approach is suitable for fields that rely on predefined options, usually set through application configurations.
At the same time, many FOLIO records contain repeatable fields that:
Allow free-text input (e.g., Series in Instance records)
Include both predefined elements and free-text (e.g., Contributors or Subjects in Instance records)
Such diversity in data entry can reduce the effectiveness of strict exact-match searches.
Requirements
Functional requirements
Support operators that are consistent with querying single value text fields but also support nature of the data in the repeatable fields:
Fields with free text values:
Equals
Not equal to
Contains
Start with
Is null/empty
Fields with predefined values:
Equals
Not equal to
In
Not in
Is null/empty
Fields with true/false values (existing behavior)
Equals
Not equal to
Is null/empty
Non-functional requirements
Response time for 10K records by query [QUERY]: [TBC]
Response time for 100K records by query [QUERY]: [TBC]
Max parallel supported operations: [TBC]
Proposed Solution
Data structures modification
Not applicable - no need to change schemas or store new data. The only existing functionality should be reworked.
Service layer modification
Changes in the mod-fqm-manager. FqlToSqlConverterService should be modified to support operators for arrayType and jsonbArrayType. Namely, the method public static Condition getSqlCondition(FqlCondition<?> fqlCondition, EntityType entityType) should be extended to support specific logic of operators for arrayType and jsonbArrayType according to the following requirements Supported Operators for Repeatable Fields :
Operator | Behaviour | Implementation | Notes |
Equals | Matches the entire value of any element in the array. The operator takes one value only. | EqualsCondition for separate branch arrayType/jsonbArrayType |
|
Not equal to | None of the array elements match the entire search text. The operator takes one value only. | NotEqualsCondition for separate branch arrayType/jsonbArrayType |
|
In | Equivalent to an OR operator across multiple values. The operator takes multiple values. | InCondition for separate branch arrayType/jsonbArrayType should be copied from ContainsAnyCondition | Corresponds contains any operator (Sunflower) |
Not in | The opposite of the “In” operator. The operator takes multiple values. | NotInCondition for separate branch arrayType/jsonbArrayType should be copied from NotContainsAnyCondition | Corresponds not contain any operator (Sunflower) |
Contains | Any element in the array contains the search text. Partial matches are supported. The operator takes one value only. | ContainsCondition for separate branch arrayType/jsonbArrayType |
|
Starts with | Any element in the array starts with the search text. The operator takes one value only. | StartsWithCondition for separate branch arrayType/jsonbArrayType |
|
Is null/empty | The array is empty. | EmptyCondition for separate branch arrayType/jsonbArrayType |
|
It is necessary to implement the operators specifically for the arrayType and jsonbArrayType branches, ensuring that existing implementations for other entityTypes remain unaffected.
Changes in lib-fqm-query-processor. Probably, validation of new entity type - operator pairs should be allowed.
Configuration modification
Each field from Repeatable Fields by Record Type should be properly configured for entity types mod-fqm-manager/src/main/resources/entity-types at master · folio-org/mod-fqm-manager to support searching.
Controllers layer modification
Not applicable
Permissions management
Not applicable
Front-end modification
Front-end should be changed to support new operators set for both predefined values and free text based on the presence of source/values for predefined values, and their absence indicates a free text argument.