fix(qdrant): support Long type in payload by converting to String

Qdrant does not support java.lang.Long as a native payload type.
Previously, passing a Long value caused the following exception:

  java.lang.IllegalArgumentException: Unsupported Qdrant value type: class java.lang.Long
    at org.springframework.ai.vectorstore.qdrant.QdrantValueFactory.value(QdrantValueFactory.java:85)
    at org.springframework.ai.vectorstore.qdrant.QdrantValueFactory.lambda$toValueMap$1(QdrantValueFactory.java:46)
    ...

To resolve this, Long values are now converted to their String representation
in QdrantValueFactory. This preserves precision and avoids serialization issues.

test(qdrant): add test to verify Long metadata values are stored as String

Adds a test to ensure that Long values in document metadata are
safely converted to String before being stored in Qdrant.

The test inserts a document with a Long-type "ref_id", performs
a similarity search, and verifies that:
- the result is not empty,
- the retrieved "ref_id" is a String,
- the value matches the original Long when parsed.

Also ensures cleanup by deleting the inserted document from the store.

Signed-off-by: Solomon Hsu <solnone@gmail.com>
(cherry picked from commit f0d4cbf037)
This commit is contained in:
Solomon Hsu
2025-05-29 11:29:33 +08:00
committed by Spring Builds
parent 7ba7727585
commit 963b9dbded
2 changed files with 24 additions and 0 deletions

View File

@@ -75,6 +75,9 @@ final class QdrantValueFactory {
return ValueFactory.value((String) value);
case "Integer":
return ValueFactory.value((Integer) value);
case "Long":
// use String representation
return ValueFactory.value(String.valueOf(value));
case "Double":
return ValueFactory.value((Double) value);
case "Float":

View File

@@ -314,6 +314,27 @@ public class QdrantVectorStoreIT extends BaseVectorStoreTests {
});
}
@Test
void shouldConvertLongToString() {
this.contextRunner.run(context -> {
QdrantVectorStore vectorStore = context.getBean(QdrantVectorStore.class);
var refId = System.currentTimeMillis();
var doc = new Document("Long type ref_id", Map.of("ref_id", refId));
vectorStore.add(List.of(doc));
List<Document> results = vectorStore
.similaritySearch(SearchRequest.builder().query("Long type ref_id").topK(1).build());
assertThat(results).hasSize(1);
Document resultDoc = results.get(0);
var resultRefId = resultDoc.getMetadata().get("ref_id");
assertThat(resultRefId).isInstanceOf(String.class);
assertThat(Double.valueOf((String) resultRefId)).isEqualTo(refId);
// Remove all documents from the store
vectorStore.delete(List.of(resultDoc.getId()));
});
}
@SpringBootConfiguration
public static class TestApplication {