Skip to content

Commit 1d21803

Browse files
committed
GH-2668 - Optimise update of relationship properties.
There is no need to fetch start and end node if we already have the identifier of the relationship to update. Closes #2668
1 parent be0ab12 commit 1d21803

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java

+19-17
Original file line numberDiff line numberDiff line change
@@ -528,27 +528,29 @@ public Statement prepareUpdateOfRelationshipsWithProperties(Neo4jPersistentEntit
528528
String row = "row";
529529
Property relationshipProperties = Cypher.property(row, Constants.NAME_OF_PROPERTIES_PARAM);
530530
Property idProperty = Cypher.property(row, Constants.FROM_ID_PARAMETER_NAME);
531-
StatementBuilder.OngoingReadingWithWhere matchStartAndEndNode =
532-
Cypher.unwind(parameter(Constants.NAME_OF_RELATIONSHIP_LIST_PARAM)).as(row)
533-
.with(row)
534-
.match(startNode)
535-
.where(neo4jPersistentEntity.isUsingInternalIds() ? internalId(startNode).isEqualTo(idProperty)
536-
: startNode.property(idPropertyName).isEqualTo(idProperty))
537-
.match(endNode).where(internalId(endNode).isEqualTo(Cypher.property(row, Constants.TO_ID_PARAMETER_NAME)));
538-
539-
StatementBuilder.ExposesSet createOrUpdateRelationship = isNew
540-
? matchStartAndEndNode.create(relationshipFragment)
541-
: matchStartAndEndNode.match(relationshipFragment)
542-
.where(Functions.id(relationshipFragment).isEqualTo(Cypher.property(row, Constants.NAME_OF_KNOWN_RELATIONSHIP_PARAM)));
531+
StatementBuilder.OrderableOngoingReadingAndWithWithoutWhere cypherUnwind = Cypher.unwind(parameter(Constants.NAME_OF_RELATIONSHIP_LIST_PARAM))
532+
.as(row)
533+
.with(row);
543534

535+
// we only need start and end node querying if we have to create a new relationship...
544536
if (isNew) {
545-
return createOrUpdateRelationship.mutate(RELATIONSHIP_NAME, relationshipProperties).returning(
546-
Functions.id(relationshipFragment).as(Constants.NAME_OF_INTERNAL_ID),
547-
Functions.elementId(relationshipFragment).as(Constants.NAME_OF_ELEMENT_ID)
548-
).build();
537+
return cypherUnwind
538+
.match(startNode)
539+
.where(neo4jPersistentEntity.isUsingInternalIds() ? internalId(startNode).isEqualTo(idProperty)
540+
: startNode.property(idPropertyName).isEqualTo(idProperty))
541+
.match(endNode).where(internalId(endNode).isEqualTo(Cypher.property(row, Constants.TO_ID_PARAMETER_NAME)))
542+
.create(relationshipFragment)
543+
.mutate(RELATIONSHIP_NAME, relationshipProperties).returning(
544+
Functions.id(relationshipFragment).as(Constants.NAME_OF_INTERNAL_ID),
545+
Functions.elementId(relationshipFragment).as(Constants.NAME_OF_ELEMENT_ID)
546+
).build();
547+
549548
}
550549

551-
return createOrUpdateRelationship.mutate(RELATIONSHIP_NAME, relationshipProperties).build();
550+
// ... otherwise we can just fetch the existing relationship by known id
551+
return cypherUnwind.match(relationshipFragment)
552+
.where(Functions.id(relationshipFragment).isEqualTo(Cypher.property(row, Constants.NAME_OF_KNOWN_RELATIONSHIP_PARAM)))
553+
.mutate(RELATIONSHIP_NAME, relationshipProperties).build();
552554
}
553555

554556
@NonNull

0 commit comments

Comments
 (0)