oscerd opened a new pull request, #29070:
URL: https://github.com/apache/camel/pull/29070

   Fixes [CAMEL-26228](https://issues.apache.org/jira/browse/CAMEL-26228), 
found while adding the catalog body types (CAMEL-24961).
   
   ## 1. CREATE_NODE with no body
   
   **Was:** `CREATE_NODE` built `Map.of("props", body)`, which threw a bare 
`NullPointerException` when the body was null. The JSON text `null` failed the 
same way, wrapped as a parse error.
   
   **Now:** Both fail with an `InvalidPayloadException` that says CREATE_NODE 
needs the properties of the node as a Map or as JSON text, before anything is 
sent to Neo4j. The error for text that is not a JSON object no longer puts the 
body in its message, since the body holds the properties of the node, which can 
be sensitive.
   
   ## 2. VECTOR_SIMILARITY_SEARCH with a List<Double> or text vector
   
   **Was:** The body was converted with `getBody(float[].class)`. A 
`List<Double>` (or a `double[]`) failed with a misleading type conversion error 
(`argument type mismatch`), and text such as `0.75,0.65` converted to null, so 
`Map.of(...)` threw a `NullPointerException`.
   
   **Now:** The vector can be a `Neo4jEmbedding`, a `float[]`, or a `List` (any 
`Collection`) or an array of numbers, each element converted with 
`floatValue()`. A list or an array with an element that is not a number fails 
with an `InvalidPayloadException` that names the index and the type of the 
element, not its value. Another body still goes through the type converters, 
and fails with an `InvalidPayloadException` that lists the accepted vectors 
when it does not convert, such as text.
   
   ## 3. A Cypher retrieve whose first column is not a node
   
   **Was:** Every record was mapped with `record.get(0).asNode()`, so 
`RETRIEVE_NODES_AND_UPDATE_WITH_CYPHER_QUERY` with a query that returns a 
property, a count or a path first failed with `Cannot coerce STRING to Node`.
   
   **Now:** A record whose first column is a node still gives the properties of 
that node. Any other record is given as a `Map` of its columns, such as 
`{name=Ethan, age=41}`.
   
   ## 4. The similarity search drops the score
   
   **Was:** The query yields `node, score`, but the body kept only the 
properties of each node.
   
   **Now:** Each `Map` of the body also has the score of the hit, as a `Double` 
under the `score` key. It replaces a property of the node named `score`; the 
records in the `CamelNeo4jQueryResultListNeo4jNodes` header keep both. The 
`text` key that the `neo4j:rag` transformer reads is unchanged.
   
   ## 5. Header metadata
   
   **Was:** `CamelNeo4jQueryResultListNeo4jNodes` was described as "Query 
execution time in Milliseconds", with type `Long`. 
`CamelNeo4jQueryResultRetrieveSize` and the four counters of the write 
operations were declared `Long`, while the producer sets an `Integer`. 
`CamelNeo4jQueryResult` was described as "Query Result", while it holds the 
text of the query that ran, and the example of `CamelNeo4jMatchProperties` 
(`{name: 'Alice'}`) is not JSON that the producer can parse. The 
`CamelNeo4jLabel` header and the `query` option were never read.
   
   **Now:** The descriptions and types say what the producer sets: `Integer`, 
and `java.util.List<org.neo4j.driver.Record>` for the records. 
`CamelNeo4jLabel` and `query` are deprecated with a deprecation note, not 
removed: `CREATE_VECTOR` takes the label from the `label` option (`Embedding` 
when it is not set), and the Cypher operations take the query from the body. 
The embeddings example of the component page no longer sets `CamelNeo4jLabel`.
   
   ## Tests
   
   `Neo4jProducerBodyTest` (18 tests) runs the producer against a fake `Driver` 
made of JDK proxies and the driver's own records and nodes, so no Neo4j server 
is needed. It covers CREATE_NODE with no body, with the JSON text `null`, with 
a Map or JSON body, and with text that is not JSON; the similarity search with 
a `List<Double>`, a `List<Float>`, a `double[]`, a `Double[]`, a `float[]` and 
a `Neo4jEmbedding`, with text, and with a List of text; the score of each hit; 
Cypher queries whose first column is a node, a property or a count; the Java 
type of the headers against their metadata; and the deprecation of the header 
and the option.
   
   With the change of `src/main` reverted, 13 of the 18 tests fail on the old 
behaviour (`NullPointerException`, `TypeConversionException`, `Cannot coerce 
... to Node`, no `score`, the `Long` metadata, the body in the message). The 5 
that pass are the cases that already worked: the search with a `List<Float>`, a 
`float[]` and a `Neo4jEmbedding`, CREATE_NODE with a Map or JSON body, and a 
Cypher query whose first column is a node.
   
   The ITs gain a similarity search with a `List<Double>`, a check of the 
`score` of each hit, a Cypher query that returns properties, and CREATE_NODE 
without a body. They need Neo4j and were not run here.
   
   Module: 25 tests, 0 failures.
   
   ## Docs and generated files
   
   The component page documents the bodies of CREATE_NODE and 
VECTOR_SIMILARITY_SEARCH, the records of a Cypher query whose first column is 
not a node, and the `score` key, and the embeddings example no longer sets the 
`CamelNeo4jLabel` header. `neo4j.json` and the component page are regenerated 
and copied to the catalog. The header and option metadata also change the 
generated endpoint DSL. The upgrade guide gets an entry for the changes users 
may notice.
   
   ## Not changed
   
   - The `CamelNeo4jLabel` header is deprecated rather than read again. 
`CREATE_VECTOR` read it until CAMEL-21719, which moved the label to the `label` 
option with `Embedding` as the default, so reading it again would revert that 
change, and it would put a header value into the Cypher text, where the label 
is not a bound parameter.
   - The `query` option is deprecated rather than used: making it the query of 
the Cypher operations would be a new feature, with an open question (the option 
or the body first).
   - Text is not parsed as a vector (such as `0.75,0.65` or a JSON array): it 
fails clearly, as the issue proposes.
   - The score goes into each `Map` rather than into a header, so it stays with 
its node; it replaces a node property named `score`.
   - The deprecated `Neo4jConstants.Headers` class keeps its old metadata, 
since the endpoint documents `Neo4jHeaders`.
   - `LangChain4jEmbeddingsComponentNeo4jTargetIT` in 
camel-langchain4j-embeddings still sets `Neo4jHeaders.LABEL`, now deprecated; 
it had no effect there before either.
   
   Main only, as the other fixes of the CAMEL-24961 follow-ups.
   
   _Claude Code on behalf of Andrea Cosentino (oscerd)_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to