Java中的Metadata Filter实现与测试详解
数据过滤是一个非常常见且重要的功能。本文记录项目实训过程中如何在Java中实现并测试Metadata Filter功能。通过一个实际的测试用例,展示如何使用自定义的过滤器对不同类型的元数据进行过滤和验证。
Metadata Filter的实现
在我们的实现中,Metadata Filter允许我们根据元数据的键和值进行过滤。以下是一个简单的示例,展示如何创建一个Metadata对象,并对其进行过滤:
import dev.langchain4j.data.document.Metadata;
public class MetadataFilter {
public static boolean isIn(Metadata metadata, String key, Object... values) {
Object metadataValue = metadata.get(key);
if (metadataValue == null) {
return false;
}
for (Object value : values) {
if (metadataValue.equals(value)) {
return true;
}
}
return false;
}
public static boolean isNotIn(Metadata metadata, String key, Object... values) {
return !isIn(metadata, key, values);
}
}
测试用例详解
为了确保我们的Metadata Filter功能正确,我们编写了一系列JUnit测试用例。以下是详细的测试代码,每个测试用例都包含了丰富的注释,以帮助理解每一步的操作。
测试字符串类型的元数据过滤
首先,我们测试字符串类型的元数据过滤。我们创建一个包含字符串值的Metadata对象,并验证各种过滤条件。
import dev.langchain4j.data.document.Metadata;
import org.junit.jupiter.api.Test;
import static dev.langchain4j.store.embedding.filter.MetadataFilterBuilder.metadataKey;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class FilterTest {
@Test
void test_in_string() {
// 创建一个Metadata对象,并添加一个键值对
Metadata metadata = new Metadata().put("id", "1");
// 验证当值在给定列表中时,过滤器应返回true
assertThat(metadataKey("id").isIn("1").test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(singletonList("1")).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn("1", "2").test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(asList("1", "2")).test(metadata)).isTrue();
// 验证当值不在给定列表中时,过滤器应返回false
assertThat(metadataKey("id").isIn("2").test(metadata)).isFalse();
assertThat(metadataKey("id").isIn("2", "3").test(metadata)).isFalse();
// 验证当类型不匹配时,应抛出IllegalArgumentException
assertThatThrownBy(() -> metadataKey("id").isIn(1).test(metadata))
.isExactlyInstanceOf(IllegalArgumentException.class)
.hasMessage("Type mismatch: actual value of metadata key \"id\" (1) " +
"has type java.lang.String, while comparison value (1) has type java.lang.Integer");
}
测试字符串类型的元数据不在列表中
@Test
void test_not_in_string() {
// 创建一个Metadata对象,并添加一个键值对
Metadata metadata = new Metadata().put("id", "1");
// 验证当值不在给定列表中时,过滤器应返回true
assertThat(metadataKey("id").isNotIn("2").test(metadata)).isTrue();
assertThat(metadataKey("id").isNotIn(singletonList("2")).test(metadata)).isTrue();
assertThat(metadataKey("id").isNotIn("2", "3").test(metadata)).isTrue();
assertThat(metadataKey("id").isNotIn(asList("2", "3")).test(metadata)).isTrue();
// 验证当值在给定列表中时,过滤器应返回false
assertThat(metadataKey("id").isNotIn("1").test(metadata)).isFalse();
assertThat(metadataKey("id").isNotIn("1", "2").test(metadata)).isFalse();
// 验证当类型不匹配时,应抛出IllegalArgumentException
assertThatThrownBy(() -> metadataKey("id").isNotIn(1).test(metadata))
.isExactlyInstanceOf(IllegalArgumentException.class)
.hasMessage("Type mismatch: actual value of metadata key \"id\" (1) " +
"has type java.lang.String, while comparison value (1) has type java.lang.Integer");
}
测试整数类型的元数据过滤
接下来,我们测试整数类型的元数据过滤。同样,我们创建一个包含整数值的Metadata对象,并验证各种过滤条件。
@Test
void test_in_integer() {
// 创建一个Metadata对象,并添加一个键值对
Metadata metadata = new Metadata().put("id", 1);
// 验证当值在给定列表中时,过滤器应返回true
assertThat(metadataKey("id").isIn(1).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(singletonList(1)).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(1, 2).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(asList(1, 2)).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(1L).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(1f).test(metadata)).isTrue();
assertThat(metadataKey("id").isIn(1d).test(metadata)).isTrue();
// 验证当值不在给定列表中时,过滤器应返回false
assertThat(metadataKey("id").isIn(2).test(metadata)).isFalse();
assertThat(metadataKey("id").isIn(2, 3).test(metadata)).isFalse();
// 验证当类型不匹配时,应抛出IllegalArgumentException
assertThatThrownBy(() -> metadataKey("id").isIn("1").test(metadata))
.isExactlyInstanceOf(IllegalArgumentException.class)
.hasMessage("Type mismatch: actual value of metadata key \"id\" (1) " +
"has type java.lang.Integer, while comparison value (1) has type java.lang.String");
}
测试整数类型的元数据不在列表中
@Test
void test_not_in_integer() {
// 创建一个Metadata对象,并添加一个键值对
Metadata metadata = new Metadata().put("id", 1);
// 验证当值不在给定列表中时,过滤器应返回true
assertThat(metadataKey("id").isNotIn(2).test(metadata)).isTrue();
assertThat(metadataKey("id").isNotIn(singletonList(2)).test(metadata)).isTrue();
assertThat(metadataKey("id").isNotIn(2, 3).test(metadata)).isTrue();
assertThat(metadataKey("id").isNotIn(asList(2, 3)).test(metadata)).isTrue();
// 验证当值在给定列表中时,过滤器应返回false
assertThat(metadataKey("id").isNotIn(1).test(metadata)).isFalse();
assertThat(metadataKey("id").isNotIn(1, 2).test(metadata)).isFalse();
assertThat(metadataKey("id").isNotIn(1L).test(metadata)).isFalse();
assertThat(metadataKey("id").isNotIn(1f).test(metadata)).isFalse();
assertThat(metadataKey("id").isNotIn(1d).test(metadata)).isFalse();
// 验证当类型不匹配时,应抛出IllegalArgumentException
assertThatThrownBy(() -> metadataKey("id").isNotIn("1").test(metadata))
.isExactlyInstanceOf(IllegalArgumentException.class)
.hasMessage("Type mismatch: actual value of metadata key \"id\" (1) " +
"has type java.lang.Integer, while comparison value (1) has type java.lang.String");
}
测试其他类型的元数据过滤
类似的,我们还可以测试长整型、浮点型、双精度型等其他类型的元数据过滤。这些测试用例的结构与上面的示例类似。
结论
通过以上详细的测试用例,我们展示了如何在Java中实现并验证Metadata Filter功能。这些测试用例不仅涵盖了不同的数据类型,还包括了各种异常情况的处理,确保了我们的过滤功能在各种情况下都能正常工作。