This is an automated email from the ASF dual-hosted git repository.
Croway pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.18.x by this push:
new 35973b037e38 CAMEL-24533: camel-weaviate - store the document text in
the object properties on CREATE/UPDATE
35973b037e38 is described below
commit 35973b037e386e7f4e6a96aa6d336083436fe41c
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Aug 31 22:26:03 2026 +0200
CAMEL-24533: camel-weaviate - store the document text in the object
properties on CREATE/UPDATE
WeaviateEmbeddingsDataTypeTransformer set the message body to the
embedding vector and only wrote the optional id into the Weaviate
object properties; the embedded text (the TextSegment body) was never
written under textFieldName, so the source passage was silently lost.
For a RAG pipeline this means the store cannot return the text that
produced a match. The Milvus sibling transformer already stores the
text correctly.
Write the text under textFieldName into the properties for CREATE and
UPDATE_BY_ID via a shared setProperties helper, merging into any
PROPERTIES header the caller already set rather than replacing it.
Also correct the default-branch error message, which claimed only
create and updatebyid were supported although query is handled too.
Co-authored-by: Claude Opus 4.8 <[email protected]>
Closes #25900
(cherry picked from commit b4c20cbed3c670c377bcb55fd7fa87429765df70)
---
.../WeaviateEmbeddingsDataTypeTransformer.java | 29 ++++--
.../WeaviateEmbeddingsDataTypeTransformerTest.java | 102 +++++++++++++++++++++
2 files changed, 123 insertions(+), 8 deletions(-)
diff --git
a/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
b/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
index f9c33054ecc1..871acea76253 100644
---
a/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
+++
b/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.weaviate.transform;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
@@ -58,7 +59,8 @@ public class WeaviateEmbeddingsDataTypeTransformer extends
Transformer {
case QUERY ->
queryEmbeddingOperation(message, embedding, vectorFieldName,
textFieldName, text, collectionName, keyValue,
keyName);
- default -> throw new IllegalStateException("The only operations
supported are create and updatebyid");
+ default ->
+ throw new IllegalStateException("The only operations supported
are create, updatebyid and query");
}
}
@@ -66,22 +68,33 @@ public class WeaviateEmbeddingsDataTypeTransformer extends
Transformer {
Message message, Embedding embedding, String vectorFieldName,
String textFieldName, TextSegment text,
String collectionName, Object keyValue, String keyName) {
message.setBody(embedding.vectorAsList(), List.class);
-
- if (ObjectHelper.isNotEmpty(keyValue) &&
ObjectHelper.isNotEmpty(keyName)) {
- HashMap<String, Object> maps = new HashMap<String, Object>();
- maps.put(keyName, keyValue);
- message.setHeader(WeaviateVectorDbHeaders.PROPERTIES, maps);
- }
+ setProperties(message, textFieldName, text, keyValue, keyName);
}
private static void updateEmbeddingOperation(
Message message, Embedding embedding, String vectorFieldName,
String textFieldName, TextSegment text,
String collectionName, Object keyValue, String keyName) {
message.setBody(embedding.vectorAsList(), List.class);
+ setProperties(message, textFieldName, text, keyValue, keyName);
+ }
+ /**
+ * Writes the object properties for a CREATE / UPDATE_BY_ID operation. The
embedded text is stored under
+ * textFieldName so that the source passage can be retrieved later;
without it only the vector (and optional id) was
+ * persisted and the original text was lost. Mirrors the Milvus
transformer. Any PROPERTIES header the caller
+ * already set is preserved: the text (and optional id) are merged into a
copy of it rather than replacing it.
+ */
+ private static void setProperties(
+ Message message, String textFieldName, TextSegment text, Object
keyValue, String keyName) {
+ Map<String, Object> existing =
message.getHeader(WeaviateVectorDbHeaders.PROPERTIES, Map.class);
+ HashMap<String, Object> maps = existing != null ? new
HashMap<>(existing) : new HashMap<>();
+ if (text != null && text.text() != null) {
+ maps.put(textFieldName, text.text());
+ }
if (ObjectHelper.isNotEmpty(keyValue) &&
ObjectHelper.isNotEmpty(keyName)) {
- HashMap<String, Object> maps = new HashMap<String, Object>();
maps.put(keyName, keyValue);
+ }
+ if (!maps.isEmpty()) {
message.setHeader(WeaviateVectorDbHeaders.PROPERTIES, maps);
}
}
diff --git
a/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
b/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
new file mode 100644
index 000000000000..d454dcb6b73b
--- /dev/null
+++
b/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.weaviate.transform;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import dev.langchain4j.data.embedding.Embedding;
+import dev.langchain4j.data.segment.TextSegment;
+import org.apache.camel.Message;
+import org.apache.camel.ai.CamelLangchain4jAttributes;
+import org.apache.camel.component.weaviate.WeaviateVectorDbAction;
+import org.apache.camel.component.weaviate.WeaviateVectorDbHeaders;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class WeaviateEmbeddingsDataTypeTransformerTest {
+
+ @SuppressWarnings("unchecked")
+ private Map<String, Object> transformProperties(WeaviateVectorDbAction
action) throws Exception {
+ Embedding embedding = new Embedding(new float[] { 0.1f, 0.2f, 0.3f });
+ TextSegment segment = TextSegment.from("the source passage");
+
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.start();
+ Message in = new DefaultExchange(context).getMessage();
+
in.setHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
embedding);
+ in.setHeader(WeaviateVectorDbHeaders.ACTION, action);
+ in.setHeader(WeaviateVectorDbHeaders.KEY_NAME, "id");
+ in.setHeader(WeaviateVectorDbHeaders.KEY_VALUE, "doc-1");
+ in.setBody(segment);
+
+ new WeaviateEmbeddingsDataTypeTransformer().transform(in,
DataType.ANY, DataType.ANY);
+
+ return in.getHeader(WeaviateVectorDbHeaders.PROPERTIES, Map.class);
+ }
+ }
+
+ @Test
+ void createStoresTheDocumentTextInProperties() throws Exception {
+ Map<String, Object> props =
transformProperties(WeaviateVectorDbAction.CREATE);
+ assertThat(props)
+ .isNotNull()
+ .containsEntry("text", "the source passage")
+ .containsEntry("id", "doc-1");
+ }
+
+ @Test
+ void updateStoresTheDocumentTextInProperties() throws Exception {
+ Map<String, Object> props =
transformProperties(WeaviateVectorDbAction.UPDATE_BY_ID);
+ assertThat(props)
+ .isNotNull()
+ .containsEntry("text", "the source passage")
+ .containsEntry("id", "doc-1");
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ void createMergesTextIntoAnExistingPropertiesHeader() throws Exception {
+ Embedding embedding = new Embedding(new float[] { 0.1f, 0.2f, 0.3f });
+ TextSegment segment = TextSegment.from("the source passage");
+
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.start();
+ Message in = new DefaultExchange(context).getMessage();
+
in.setHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
embedding);
+ in.setHeader(WeaviateVectorDbHeaders.ACTION,
WeaviateVectorDbAction.CREATE);
+ // Properties the caller populated before the transformer runs
must survive.
+ Map<String, Object> callerProperties = new HashMap<>();
+ callerProperties.put("sky", "blue");
+ callerProperties.put("age", "34");
+ in.setHeader(WeaviateVectorDbHeaders.PROPERTIES, callerProperties);
+ in.setBody(segment);
+
+ new WeaviateEmbeddingsDataTypeTransformer().transform(in,
DataType.ANY, DataType.ANY);
+
+ Map<String, Object> props =
in.getHeader(WeaviateVectorDbHeaders.PROPERTIES, Map.class);
+ assertThat(props)
+ .containsEntry("sky", "blue")
+ .containsEntry("age", "34")
+ .containsEntry("text", "the source passage");
+ }
+ }
+}