Skip to content

Commit 6a3c548

Browse files
Oleksandr Klymenkomarkpollack
authored andcommitted
Refactor to modern switch expressions in vector stores
Replace traditional switch statements with Java 14 switch expressions across vector store filter converters and related components. This change improves code quality in our filter expression handling for Azure, Milvus, Redis, Typesense and Weaviate implementations. The switch expressions eliminate fall-through behavior, enforce exhaustive pattern matching at compile time, and provide a more direct way to return values. This makes the filter conversion logic more robust and maintainable.
1 parent 5235696 commit 6a3c548

File tree

6 files changed

+76
-133
lines changed

6 files changed

+76
-133
lines changed

vector-stores/spring-ai-azure-store/src/main/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverter.java

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,30 +80,19 @@ protected void doEndValueRange(Filter.Value listValue, StringBuilder context) {
8080
}
8181

8282
private String getOperationSymbol(Expression exp) {
83-
switch (exp.type()) {
84-
case AND:
85-
return " and ";
86-
case OR:
87-
return " or ";
88-
case EQ:
89-
return " eq ";
90-
case NE:
91-
return " ne ";
92-
case LT:
93-
return " lt ";
94-
case LTE:
95-
return " le ";
96-
case GT:
97-
return " gt ";
98-
case GTE:
99-
return " ge ";
100-
case IN:
101-
return " search.in";
102-
case NIN:
103-
return " not search.in";
104-
default:
105-
throw new RuntimeException("Not supported expression type: " + exp.type());
106-
}
83+
return switch (exp.type()) {
84+
case AND -> " and ";
85+
case OR -> " or ";
86+
case EQ -> " eq ";
87+
case NE -> " ne ";
88+
case LT -> " lt ";
89+
case LTE -> " le ";
90+
case GT -> " gt ";
91+
case GTE -> " ge ";
92+
case IN -> " search.in";
93+
case NIN -> " not search.in";
94+
default -> throw new RuntimeException("Not supported expression type: " + exp.type());
95+
};
10796
}
10897

10998
@Override

vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/MilvusFilterExpressionConverter.java

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,19 @@ protected void doExpression(Expression exp, StringBuilder context) {
3838
}
3939

4040
private String getOperationSymbol(Expression exp) {
41-
switch (exp.type()) {
42-
case AND:
43-
return " && ";
44-
case OR:
45-
return " || ";
46-
case EQ:
47-
return " == ";
48-
case NE:
49-
return " != ";
50-
case LT:
51-
return " < ";
52-
case LTE:
53-
return " <= ";
54-
case GT:
55-
return " > ";
56-
case GTE:
57-
return " >= ";
58-
case IN:
59-
return " in ";
60-
case NIN:
61-
return " not in ";
62-
default:
63-
throw new RuntimeException("Not supported expression type:" + exp.type());
64-
}
41+
return switch (exp.type()) {
42+
case AND -> " && ";
43+
case OR -> " || ";
44+
case EQ -> " == ";
45+
case NE -> " != ";
46+
case LT -> " < ";
47+
case LTE -> " <= ";
48+
case GT -> " > ";
49+
case GTE -> " >= ";
50+
case IN -> " in ";
51+
case NIN -> " not in ";
52+
default -> throw new RuntimeException("Not supported expression type:" + exp.type());
53+
};
6554
}
6655

6756
@Override

vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/RedisFilterExpressionConverter.java

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -140,33 +140,24 @@ private Object stringValue(Expression expression, Value value) {
140140
}
141141

142142
private String tagValueDelimiter(Expression expression) {
143-
switch (expression.type()) {
144-
case IN:
145-
return " | ";
146-
case EQ:
147-
return " ";
148-
default:
149-
throw new UnsupportedOperationException(
150-
MessageFormat.format("Tag operand {0} not supported", expression.type()));
151-
}
143+
return switch (expression.type()) {
144+
case IN -> " | ";
145+
case EQ -> " ";
146+
default -> throw new UnsupportedOperationException(
147+
MessageFormat.format("Tag operand {0} not supported", expression.type()));
148+
};
152149
}
153150

154151
private Numeric numeric(Expression expression, Value value) {
155-
switch (expression.type()) {
156-
case EQ:
157-
return new Numeric(inclusive(value), inclusive(value));
158-
case GT:
159-
return new Numeric(exclusive(value), POSITIVE_INFINITY);
160-
case GTE:
161-
return new Numeric(inclusive(value), POSITIVE_INFINITY);
162-
case LT:
163-
return new Numeric(NEGATIVE_INFINITY, exclusive(value));
164-
case LTE:
165-
return new Numeric(NEGATIVE_INFINITY, inclusive(value));
166-
default:
167-
throw new UnsupportedOperationException(MessageFormat
168-
.format("Expression type {0} not supported for numeric fields", expression.type()));
169-
}
152+
return switch (expression.type()) {
153+
case EQ -> new Numeric(inclusive(value), inclusive(value));
154+
case GT -> new Numeric(exclusive(value), POSITIVE_INFINITY);
155+
case GTE -> new Numeric(inclusive(value), POSITIVE_INFINITY);
156+
case LT -> new Numeric(NEGATIVE_INFINITY, exclusive(value));
157+
case LTE -> new Numeric(NEGATIVE_INFINITY, inclusive(value));
158+
default -> throw new UnsupportedOperationException(
159+
MessageFormat.format("Expression type {0} not supported for numeric fields", expression.type()));
160+
};
170161
}
171162

172163
private NumericBoundary inclusive(Value value) {

vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/RedisVectorStore.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,17 +305,13 @@ private Iterable<SchemaField> schemaFields() {
305305

306306
private SchemaField schemaField(MetadataField field) {
307307
String fieldName = jsonPath(field.name);
308-
switch (field.fieldType) {
309-
case NUMERIC:
310-
return NumericField.of(fieldName).as(field.name);
311-
case TAG:
312-
return TagField.of(fieldName).as(field.name);
313-
case TEXT:
314-
return TextField.of(fieldName).as(field.name);
315-
default:
316-
throw new IllegalArgumentException(
317-
MessageFormat.format("Field {0} has unsupported type {1}", field.name, field.fieldType));
318-
}
308+
return switch (field.fieldType) {
309+
case NUMERIC -> NumericField.of(fieldName).as(field.name);
310+
case TAG -> TagField.of(fieldName).as(field.name);
311+
case TEXT -> TextField.of(fieldName).as(field.name);
312+
default -> throw new IllegalArgumentException(
313+
MessageFormat.format("Field {0} has unsupported type {1}", field.name, field.fieldType));
314+
};
319315
}
320316

321317
private VectorAlgorithm vectorAlgorithm() {

vector-stores/spring-ai-typesense-store/src/main/java/org/springframework/ai/vectorstore/TypesenseFilterExpressionConverter.java

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,20 @@ protected void doExpression(Filter.Expression exp, StringBuilder context) {
3535
}
3636

3737
private String getOperationSymbol(Filter.Expression exp) {
38-
switch (exp.type()) {
39-
case AND:
40-
return " && ";
41-
case OR:
42-
return " || ";
43-
case EQ:
44-
return " "; // in typesense "EQ" operator looks like -> country:USA
45-
case NE:
46-
return " != ";
47-
case LT:
48-
return " < ";
49-
case LTE:
50-
return " <= ";
51-
case GT:
52-
return " > ";
53-
case GTE:
54-
return " >= ";
55-
case IN:
56-
return " "; // in typesense "IN" operator looks like -> country: [USA, UK]
57-
case NIN:
58-
return " != "; // in typesense "NIN" operator looks like -> country:
38+
return switch (exp.type()) {
39+
case AND -> " && ";
40+
case OR -> " || ";
41+
case EQ -> " "; // in typesense "EQ" operator looks like -> country:USA
42+
case NE -> " != ";
43+
case LT -> " < ";
44+
case LTE -> " <= ";
45+
case GT -> " > ";
46+
case GTE -> " >= ";
47+
case IN -> " "; // in typesense "IN" operator looks like -> country: [USA, UK]
48+
case NIN -> " != "; // in typesense "NIN" operator looks like -> country:
5949
// !=[USA, UK]
60-
default:
61-
throw new RuntimeException("Not supported expression type:" + exp.type());
62-
}
50+
default -> throw new RuntimeException("Not supported expression type:" + exp.type());
51+
};
6352
}
6453

6554
@Override

vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/WeaviateFilterExpressionConverter.java

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -83,32 +83,21 @@ else if (exp.type() == ExpressionType.AND || exp.type() == ExpressionType.OR) {
8383
}
8484

8585
private String getOperationSymbol(Expression exp) {
86-
switch (exp.type()) {
87-
case AND:
88-
return "operator:And \n";
89-
case OR:
90-
return "operator:Or \n";
91-
case EQ:
92-
return "operator:Equal \n";
93-
case NE:
94-
return "operator:NotEqual \n";
95-
case LT:
96-
return "operator:LessThan \n";
97-
case LTE:
98-
return "operator:LessThanEqual \n";
99-
case GT:
100-
return "operator:GreaterThan \n";
101-
case GTE:
102-
return "operator:GreaterThanEqual \n";
103-
case IN:
104-
throw new IllegalStateException(
105-
"The 'IN' operator should have been transformed into chain of OR/EQ expressions.");
106-
case NIN:
107-
throw new IllegalStateException(
108-
"The 'NIN' operator should have been transformed into chain of AND/NEQ expressions.");
109-
default:
110-
throw new UnsupportedOperationException("Not supported expression type:" + exp.type());
111-
}
86+
return switch (exp.type()) {
87+
case AND -> "operator:And \n";
88+
case OR -> "operator:Or \n";
89+
case EQ -> "operator:Equal \n";
90+
case NE -> "operator:NotEqual \n";
91+
case LT -> "operator:LessThan \n";
92+
case LTE -> "operator:LessThanEqual \n";
93+
case GT -> "operator:GreaterThan \n";
94+
case GTE -> "operator:GreaterThanEqual \n";
95+
case IN -> throw new IllegalStateException(
96+
"The 'IN' operator should have been transformed into chain of OR/EQ expressions.");
97+
case NIN -> throw new IllegalStateException(
98+
"The 'NIN' operator should have been transformed into chain of AND/NEQ expressions.");
99+
default -> throw new UnsupportedOperationException("Not supported expression type:" + exp.type());
100+
};
112101
}
113102

114103
@Override

0 commit comments

Comments
 (0)