Skip to content

Commit 93146df

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 6bee8d0 commit 93146df

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
@@ -527,27 +527,29 @@ public Statement prepareUpdateOfRelationshipsWithProperties(Neo4jPersistentEntit
527527
String row = "row";
528528
Property relationshipProperties = Cypher.property(row, Constants.NAME_OF_PROPERTIES_PARAM);
529529
Property idProperty = Cypher.property(row, Constants.FROM_ID_PARAMETER_NAME);
530-
StatementBuilder.OngoingReadingWithWhere matchStartAndEndNode =
531-
Cypher.unwind(parameter(Constants.NAME_OF_RELATIONSHIP_LIST_PARAM)).as(row)
532-
.with(row)
533-
.match(startNode)
534-
.where(neo4jPersistentEntity.isUsingInternalIds() ? internalId(startNode).isEqualTo(idProperty)
535-
: startNode.property(idPropertyName).isEqualTo(idProperty))
536-
.match(endNode).where(internalId(endNode).isEqualTo(Cypher.property(row, Constants.TO_ID_PARAMETER_NAME)));
537-
538-
StatementBuilder.ExposesSet createOrUpdateRelationship = isNew
539-
? matchStartAndEndNode.create(relationshipFragment)
540-
: matchStartAndEndNode.match(relationshipFragment)
541-
.where(Functions.id(relationshipFragment).isEqualTo(Cypher.property(row, Constants.NAME_OF_KNOWN_RELATIONSHIP_PARAM)));
530+
StatementBuilder.OrderableOngoingReadingAndWithWithoutWhere cypherUnwind = Cypher.unwind(parameter(Constants.NAME_OF_RELATIONSHIP_LIST_PARAM))
531+
.as(row)
532+
.with(row);
542533

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

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

553555
@NonNull

0 commit comments

Comments
 (0)