Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-19-2021 03:06 AM
I have written test code to connect to neo4j server from java app and execute two cypher queries in ONE Transaction.I did not find detailed example for executing two queries and retrieving result in neo4j Documentation
Though the code works, my question is:
Other details:
Please find attached java test code.
Neo4jConnectorTest.java.txt (7.0 KB)
01-25-2021 02:33 AM
Disclaimer: I am not super familiar with these Java APIs
I noticed a few things.
The most important one, in my opinion, is that you could rewrite everything into a single Cypher query with UNWIND $product_ids AS id MERGE (p:Product {id: id }) RETURN p.id
and retrieve each row, instead of composing several queries' result, that would probably simplify the code quite a bit. Note that the initial ON CREATE
clause is not needed, because MERGE
already CREATE
s everything defined in the pattern if the pattern is not MATCH
ed in the graph (in that case, the id
attribute is part of the pattern so it will be created if absent).
Then, a few technical details that I noticed:
Before calling java.util.concurrent.CompletableFuture#allOf
, you should convert every CompletionStage
to CompletableFuture
with java.util.concurrent.CompletionStage#toCompletableFuture
(it might be a no-op today, but that's not guaranteed in the future). Indeed, the toArray
call is otherwise unsafe.
I also wonder if the code could not be simplified if you call join
on the allOf
result, surrounding the call with a try-catch:
try {
CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).join();
// all queries have returned: now, extract results & commit tx
} catch (CancellationException | CompletionException e) {
return tx.rollbackAsync();
}
01-26-2021 09:58 PM
Thank you @florent.biville1 for the response,
Using join
has simplified the code a lot and I have updated the implementation to convert CompletionStage
to CompletableFuture
now.
Also, our actual queries are quite different, I used those queries just to test (Apologies, if it was not clear earlier). Sharing few actual queries:
MATCH (entity:Entity { id: 'Default/CAMR-Finance25/Account/c5abf4a2-aecf-4bb4-a830-98a2af92cd91'}) WITH entity
MERGE (alert:Alert { id: 'Default/CAMR-Finance25/Account/c5abf4a2-aecf-4bb4-a830-98a2af92cd91' ,taskId: 1161 ,alertType: 'IdentityStatusValidation' ,entityGlobalId: 'c5abf4a2-aecf-4bb4-a830-98a2af92cd91' })
ON CREATE SET
alert.id = 'Default/CAMR-Finance25/Account/c5abf4a2-aecf-4bb4-a830-98a2af92cd91' ,alert.taskId= 1161 ,alert.alertType= 'IdentityStatusValidation' ,alert.entityGlobalId= 'c5abf4a2-aecf-4bb4-a830-98a2af92cd91' ,alert.raisedTime= 1610010155452 ,alert.summary= 'IdentityStatusValidation has failed, Please check task messages for more details.' ,alert.messages= '[{"message":"User ( [MMISHRA] ) could not be found. A valid and active User ID must be provided.","severity":"WARNING"}]'
ON MATCH SET
alert.id = 'Default/CAMR-Finance25/Account/c5abf4a2-aecf-4bb4-a830-98a2af92cd91' ,alert.taskId= 1161 ,alert.alertType= 'IdentityStatusValidation' ,alert.entityGlobalId= 'c5abf4a2-aecf-4bb4-a830-98a2af92cd91' ,alert.updateTime= 1610340489245 ,alert.summary= 'IdentityStatusValidation has failed, Please check task messages for more details.' ,alert.messages= '[{"message":"User ( [MMISHRA] ) could not be found. A valid and active User ID must be provided.","severity":"WARNING"}]'
MERGE (entity)-[r:WITH_ALERT]->(alert)
I haved attached the updated code.Neo4jConnectorTest.java-updated.txt (6.0 KB)
01-27-2021 03:12 AM
Nice, it's good to know you could simplify the code
My initial remark about MERGE
and ON CREATE
/ON MATCH
still applies: you should not include attributes in these clauses that are already part of the MERGE
pattern (i.e. remove id
, taskId
, alertType
and entityGlobalId
from the ON xxx SET
clauses).
Moreover, if you need to set properties in both ON CREATE
/ON MATCH
cases, you can simply write MERGE... SET
(without ON CREATE
/ON MATCH
), it will set the properties all the time (which could be useful for the messages
and summary
).
In short, your example query would become:
MATCH (entity:Entity { id: 'Default/CAMR-Finance25/Account/c5abf4a2-aecf-4bb4-a830-98a2af92cd91'})
MERGE (alert:Alert {
id: 'Default/CAMR-Finance25/Account/c5abf4a2-aecf-4bb4-a830-98a2af92cd91',
taskId: 1161,
alertType: 'IdentityStatusValidation',
entityGlobalId: 'c5abf4a2-aecf-4bb4-a830-98a2af92cd91'
})
ON CREATE SET alert.raisedTime = 1610010155452
ON MATCH SET alert.updateTime = 1610340489245
SET alert.summary= 'IdentityStatusValidation has failed, Please check task messages for more details.' ,
alert.messages= '[{"message":"User ( [MMISHRA] ) could not be found. A valid and active User ID must be provided.","severity":"WARNING"}]'
MERGE (entity)-[r:WITH_ALERT]->(alert)
All the sessions of the conference are now available online