Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.EQ;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.GT;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.GTE;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.IN;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.LT;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.LTE;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NE;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NIN;
Expand Down Expand Up @@ -123,4 +125,172 @@ public void testComplexIdentifiers() {
assertThat(vectorExpr).isEqualTo("{\"metadata.country 1 2 3\":{$eq:\"BG\"}}");
}

@Test
public void testLt() {
// value < 100
String vectorExpr = this.converter.convertExpression(new Expression(LT, new Key("value"), new Value(100)));
assertThat(vectorExpr).isEqualTo("{\"metadata.value\":{$lt:100}}");
}

@Test
public void testLte() {
// value <= 100
String vectorExpr = this.converter.convertExpression(new Expression(LTE, new Key("value"), new Value(100)));
assertThat(vectorExpr).isEqualTo("{\"metadata.value\":{$lte:100}}");
}

@Test
public void testGt() {
// value > 100
String vectorExpr = this.converter.convertExpression(new Expression(GT, new Key("value"), new Value(100)));
assertThat(vectorExpr).isEqualTo("{\"metadata.value\":{$gt:100}}");
}

@Test
public void testNin() {
// region not in ["A", "B", "C"]
String vectorExpr = this.converter
.convertExpression(new Expression(NIN, new Key("region"), new Value(List.of("A", "B", "C"))));
assertThat(vectorExpr).isEqualTo("{\"metadata.region\":{$nin:[\"A\",\"B\",\"C\"]}}");
}

@Test
public void testComplexNestedGroups() {
// ((value >= 100 AND type == "primary") OR (value <= 50 AND type == "secondary"))
// AND region == "X"
String vectorExpr = this.converter.convertExpression(new Expression(AND,
new Group(new Expression(OR,
new Group(new Expression(AND, new Expression(GTE, new Key("value"), new Value(100)),
new Expression(EQ, new Key("type"), new Value("primary")))),
new Group(new Expression(AND, new Expression(LTE, new Key("value"), new Value(50)),
new Expression(EQ, new Key("type"), new Value("secondary")))))),
new Expression(EQ, new Key("region"), new Value("X"))));

assertThat(vectorExpr).isEqualTo(
"{$and:[{$or:[{$and:[{\"metadata.value\":{$gte:100}},{\"metadata.type\":{$eq:\"primary\"}}]},{$and:[{\"metadata.value\":{$lte:50}},{\"metadata.type\":{$eq:\"secondary\"}}]}]},{\"metadata.region\":{$eq:\"X\"}}]}");
}

@Test
public void testNullValue() {
// status == null
String vectorExpr = this.converter.convertExpression(new Expression(EQ, new Key("status"), new Value(null)));
assertThat(vectorExpr).isEqualTo("{\"metadata.status\":{$eq:null}}");
}

@Test
public void testEmptyString() {
// name == ""
String vectorExpr = this.converter.convertExpression(new Expression(EQ, new Key("name"), new Value("")));
assertThat(vectorExpr).isEqualTo("{\"metadata.name\":{$eq:\"\"}}");
}

@Test
public void testNumericString() {
// id == "12345"
String vectorExpr = this.converter.convertExpression(new Expression(EQ, new Key("id"), new Value("12345")));
assertThat(vectorExpr).isEqualTo("{\"metadata.id\":{$eq:\"12345\"}}");
}

@Test
public void testLongValue() {
// timestamp >= 1640995200000L
String vectorExpr = this.converter
.convertExpression(new Expression(GTE, new Key("timestamp"), new Value(1640995200000L)));
assertThat(vectorExpr).isEqualTo("{\"metadata.timestamp\":{$gte:1640995200000}}");
}

@Test
public void testFloatValue() {
// score >= 4.5f
String vectorExpr = this.converter.convertExpression(new Expression(GTE, new Key("score"), new Value(4.5f)));
assertThat(vectorExpr).isEqualTo("{\"metadata.score\":{$gte:4.5}}");
}

@Test
public void testMixedTypesList() {
// tags in [1, "priority", true]
String vectorExpr = this.converter
.convertExpression(new Expression(IN, new Key("tags"), new Value(List.of(1, "priority", true))));
assertThat(vectorExpr).isEqualTo("{\"metadata.tags\":{$in:[1,\"priority\",true]}}");
}

@Test
public void testEmptyList() {
// categories in []
String vectorExpr = this.converter
.convertExpression(new Expression(IN, new Key("categories"), new Value(List.of())));
assertThat(vectorExpr).isEqualTo("{\"metadata.categories\":{$in:[]}}");
}

@Test
public void testSingleItemList() {
// status in ["active"]
String vectorExpr = this.converter
.convertExpression(new Expression(IN, new Key("status"), new Value(List.of("active"))));
assertThat(vectorExpr).isEqualTo("{\"metadata.status\":{$in:[\"active\"]}}");
}

@Test
public void testKeyWithDots() {
// "value.field" >= 18
String vectorExpr = this.converter
.convertExpression(new Expression(GTE, new Key("value.field"), new Value(18)));
assertThat(vectorExpr).isEqualTo("{\"metadata.value.field\":{$gte:18}}");
}

@Test
public void testKeyWithSpecialCharacters() {
// "field-name_with@symbols" == "value"
String vectorExpr = this.converter
.convertExpression(new Expression(EQ, new Key("field-name_with@symbols"), new Value("value")));
assertThat(vectorExpr).isEqualTo("{\"metadata.field-name_with@symbols\":{$eq:\"value\"}}");
}

@Test
public void testTripleAnd() {
// value >= 100 AND type == "primary" AND region == "X"
String vectorExpr = this.converter.convertExpression(new Expression(AND,
new Expression(AND, new Expression(GTE, new Key("value"), new Value(100)),
new Expression(EQ, new Key("type"), new Value("primary"))),
new Expression(EQ, new Key("region"), new Value("X"))));

assertThat(vectorExpr).isEqualTo(
"{$and:[{$and:[{\"metadata.value\":{$gte:100}},{\"metadata.type\":{$eq:\"primary\"}}]},{\"metadata.region\":{$eq:\"X\"}}]}");
}

@Test
public void testTripleOr() {
// value < 50 OR value > 200 OR type == "special"
String vectorExpr = this.converter.convertExpression(new Expression(OR,
new Expression(OR, new Expression(LT, new Key("value"), new Value(50)),
new Expression(GT, new Key("value"), new Value(200))),
new Expression(EQ, new Key("type"), new Value("special"))));

assertThat(vectorExpr).isEqualTo(
"{$or:[{$or:[{\"metadata.value\":{$lt:50}},{\"metadata.value\":{$gt:200}}]},{\"metadata.type\":{$eq:\"special\"}}]}");
}

@Test
public void testZeroValues() {
// count == 0
String vectorExpr = this.converter.convertExpression(new Expression(EQ, new Key("count"), new Value(0)));
assertThat(vectorExpr).isEqualTo("{\"metadata.count\":{$eq:0}}");
}

@Test
public void testBooleanFalse() {
// enabled == false
String vectorExpr = this.converter.convertExpression(new Expression(EQ, new Key("enabled"), new Value(false)));
assertThat(vectorExpr).isEqualTo("{\"metadata.enabled\":{$eq:false}}");
}

@Test
public void testVeryLongString() {
// Test with a very long string value
String longValue = "This is a very long string that might be used as a value in a filter expression to test how the converter handles lengthy text content that could potentially cause issues with string manipulation or JSON formatting";
String vectorExpr = this.converter
.convertExpression(new Expression(EQ, new Key("content"), new Value(longValue)));
assertThat(vectorExpr).isEqualTo("{\"metadata.content\":{$eq:\"" + longValue + "\"}}");
}

}