-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[eqFmcQxi] Fix bug with apoc.export.cypher.* where temp. rel properties were not cleaned up. #632
Conversation
As preparation for adding corresponding methods for relationships.
6124736
to
49c7d4d
Compare
…es were not cleaned up. The bug was only affecting users who have set the `multipleRelationshipsWithType` configuration option to true.
49c7d4d
to
e6897f7
Compare
/* | ||
* Returns true if there exists no other relationship with the same start node, end node and type | ||
*/ | ||
public static boolean isUniqueRelationship(Relationship rel) { | ||
return StreamSupport.stream( | ||
rel.getStartNode() | ||
.getRelationships(Direction.OUTGOING, rel.getType()) | ||
.spliterator(), | ||
false) | ||
.noneMatch(r -> !r.equals(rel) && r.getEndNode().equals(rel.getEndNode())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this really do what it says it does?
I'm thinking about this situation:
create (a), (b)
with a,b
create (a)-[:R]->(b)
with a,b
create (a)-[:R]->(b)
Relationship.equals looks like it's implemented based on id:
@Override
public boolean equals(Object o) {
return o instanceof Relationship && this.getId() == ((Relationship) o).getId();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, never mind, now I see it.
@@ -27,75 +27,75 @@ UNWIND [{_id:160, properties:{born:1967, name:"Julia Roberts", id:"a81fe3a2-68a0 | |||
CREATE (n:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`: row._id}) SET n += row.properties SET n:Person:Other; | |||
:commit | |||
:begin | |||
UNWIND [{start: {_id:38}, id: 0, end: {_id:0}, properties:{roles:["Neo"], `UNIQUE IMPORT ID REL`:0}}, {start: {_id:39}, id: 1, end: {_id:0}, properties:{roles:["Trinity"], `UNIQUE IMPORT ID REL`:1}}, {start: {_id:40}, id: 2, end: {_id:0}, properties:{roles:["Morpheus"], `UNIQUE IMPORT ID REL`:2}}, {start: {_id:41}, id: 3, end: {_id:0}, properties:{roles:["Agent Smith"], `UNIQUE IMPORT ID REL`:3}}, {start: {_id:45}, id: 4, end: {_id:0}, properties:{roles:["Emil"], `UNIQUE IMPORT ID REL`:7}}, {start: {_id:38}, id: 5, end: {_id:1}, properties:{roles:["Neo"], `UNIQUE IMPORT ID REL`:8}}, {start: {_id:39}, id: 6, end: {_id:1}, properties:{roles:["Trinity"], `UNIQUE IMPORT ID REL`:9}}, {start: {_id:40}, id: 7, end: {_id:1}, properties:{roles:["Morpheus"], `UNIQUE IMPORT ID REL`:10}}, {start: {_id:41}, id: 8, end: {_id:1}, properties:{roles:["Agent Smith"], `UNIQUE IMPORT ID REL`:11}}, {start: {_id:38}, id: 9, end: {_id:2}, properties:{roles:["Neo"], `UNIQUE IMPORT ID REL`:15}}, {start: {_id:39}, id: 10, end: {_id:2}, properties:{roles:["Trinity"], `UNIQUE IMPORT ID REL`:16}}, {start: {_id:40}, id: 11, end: {_id:2}, properties:{roles:["Morpheus"], `UNIQUE IMPORT ID REL`:17}}, {start: {_id:41}, id: 12, end: {_id:2}, properties:{roles:["Agent Smith"], `UNIQUE IMPORT ID REL`:18}}, {start: {_id:38}, id: 13, end: {_id:3}, properties:{roles:["Kevin Lomax"], `UNIQUE IMPORT ID REL`:22}}, {start: {_id:46}, id: 14, end: {_id:3}, properties:{roles:["Mary Ann Lomax"], `UNIQUE IMPORT ID REL`:23}}, {start: {_id:47}, id: 15, end: {_id:3}, properties:{roles:["John Milton"], `UNIQUE IMPORT ID REL`:24}}, {start: {_id:49}, id: 16, end: {_id:4}, properties:{roles:["Lt. Daniel Kaffee"], `UNIQUE IMPORT ID REL`:26}}, {start: {_id:50}, id: 17, end: {_id:4}, properties:{roles:["Col. Nathan R. Jessup"], `UNIQUE IMPORT ID REL`:27}}, {start: {_id:51}, id: 18, end: {_id:4}, properties:{roles:["Lt. Cdr. JoAnne Galloway"], `UNIQUE IMPORT ID REL`:28}}, {start: {_id:52}, id: 19, end: {_id:4}, properties:{roles:["Capt. Jack Ross"], `UNIQUE IMPORT ID REL`:29}}] AS row | |||
UNWIND [{start: {_id:38}, id: 0, end: {_id:0}, properties:{roles:["Neo"]}}, {start: {_id:39}, id: 1, end: {_id:0}, properties:{roles:["Trinity"]}}, {start: {_id:40}, id: 2, end: {_id:0}, properties:{roles:["Morpheus"]}}, {start: {_id:41}, id: 3, end: {_id:0}, properties:{roles:["Agent Smith"]}}, {start: {_id:45}, id: 4, end: {_id:0}, properties:{roles:["Emil"]}}, {start: {_id:38}, id: 5, end: {_id:1}, properties:{roles:["Neo"]}}, {start: {_id:39}, id: 6, end: {_id:1}, properties:{roles:["Trinity"]}}, {start: {_id:40}, id: 7, end: {_id:1}, properties:{roles:["Morpheus"]}}, {start: {_id:41}, id: 8, end: {_id:1}, properties:{roles:["Agent Smith"]}}, {start: {_id:38}, id: 9, end: {_id:2}, properties:{roles:["Neo"]}}, {start: {_id:39}, id: 10, end: {_id:2}, properties:{roles:["Trinity"]}}, {start: {_id:40}, id: 11, end: {_id:2}, properties:{roles:["Morpheus"]}}, {start: {_id:41}, id: 12, end: {_id:2}, properties:{roles:["Agent Smith"]}}, {start: {_id:38}, id: 13, end: {_id:3}, properties:{roles:["Kevin Lomax"]}}, {start: {_id:46}, id: 14, end: {_id:3}, properties:{roles:["Mary Ann Lomax"]}}, {start: {_id:47}, id: 15, end: {_id:3}, properties:{roles:["John Milton"]}}, {start: {_id:49}, id: 16, end: {_id:4}, properties:{roles:["Lt. Daniel Kaffee"]}}, {start: {_id:50}, id: 17, end: {_id:4}, properties:{roles:["Col. Nathan R. Jessup"]}}, {start: {_id:51}, id: 18, end: {_id:4}, properties:{roles:["Lt. Cdr. JoAnne Galloway"]}}, {start: {_id:52}, id: 19, end: {_id:4}, properties:{roles:["Capt. Jack Ross"]}}] AS row |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not follow, why did this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it that the bug was that UNIQUE IMPORT ID REL
properties are supposed to be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I also got confused by this. I think to get the roundtrip to work despite the bug someone (@gem-neo4j ?) had coded this file as if the user already had UNIQUE IMPORT ID REL
properties in their data before calling APOC (like if they had added it manually). One could argue that in this unlikely event the code is broken after the bug fix as we throw away their properties. However it is the same for nodes and there is a setting to turn off this behaviour, so I would say it is OK
@@ -27,75 +27,75 @@ UNWIND [{_id:160, properties:{born:1967, name:"Julia Roberts", id:"a81fe3a2-68a0 | |||
CREATE (n:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`: row._id}) SET n += row.properties SET n:Person:Other; | |||
:commit | |||
:begin | |||
UNWIND [{start: {_id:38}, id: 0, end: {_id:0}, properties:{roles:["Neo"], `UNIQUE IMPORT ID REL`:0}}, {start: {_id:39}, id: 1, end: {_id:0}, properties:{roles:["Trinity"], `UNIQUE IMPORT ID REL`:1}}, {start: {_id:40}, id: 2, end: {_id:0}, properties:{roles:["Morpheus"], `UNIQUE IMPORT ID REL`:2}}, {start: {_id:41}, id: 3, end: {_id:0}, properties:{roles:["Agent Smith"], `UNIQUE IMPORT ID REL`:3}}, {start: {_id:45}, id: 4, end: {_id:0}, properties:{roles:["Emil"], `UNIQUE IMPORT ID REL`:7}}, {start: {_id:38}, id: 5, end: {_id:1}, properties:{roles:["Neo"], `UNIQUE IMPORT ID REL`:8}}, {start: {_id:39}, id: 6, end: {_id:1}, properties:{roles:["Trinity"], `UNIQUE IMPORT ID REL`:9}}, {start: {_id:40}, id: 7, end: {_id:1}, properties:{roles:["Morpheus"], `UNIQUE IMPORT ID REL`:10}}, {start: {_id:41}, id: 8, end: {_id:1}, properties:{roles:["Agent Smith"], `UNIQUE IMPORT ID REL`:11}}, {start: {_id:38}, id: 9, end: {_id:2}, properties:{roles:["Neo"], `UNIQUE IMPORT ID REL`:15}}, {start: {_id:39}, id: 10, end: {_id:2}, properties:{roles:["Trinity"], `UNIQUE IMPORT ID REL`:16}}, {start: {_id:40}, id: 11, end: {_id:2}, properties:{roles:["Morpheus"], `UNIQUE IMPORT ID REL`:17}}, {start: {_id:41}, id: 12, end: {_id:2}, properties:{roles:["Agent Smith"], `UNIQUE IMPORT ID REL`:18}}, {start: {_id:38}, id: 13, end: {_id:3}, properties:{roles:["Kevin Lomax"], `UNIQUE IMPORT ID REL`:22}}, {start: {_id:46}, id: 14, end: {_id:3}, properties:{roles:["Mary Ann Lomax"], `UNIQUE IMPORT ID REL`:23}}, {start: {_id:47}, id: 15, end: {_id:3}, properties:{roles:["John Milton"], `UNIQUE IMPORT ID REL`:24}}, {start: {_id:49}, id: 16, end: {_id:4}, properties:{roles:["Lt. Daniel Kaffee"], `UNIQUE IMPORT ID REL`:26}}, {start: {_id:50}, id: 17, end: {_id:4}, properties:{roles:["Col. Nathan R. Jessup"], `UNIQUE IMPORT ID REL`:27}}, {start: {_id:51}, id: 18, end: {_id:4}, properties:{roles:["Lt. Cdr. JoAnne Galloway"], `UNIQUE IMPORT ID REL`:28}}, {start: {_id:52}, id: 19, end: {_id:4}, properties:{roles:["Capt. Jack Ross"], `UNIQUE IMPORT ID REL`:29}}] AS row | |||
UNWIND [{start: {_id:38}, id: 0, end: {_id:0}, properties:{roles:["Neo"]}}, {start: {_id:39}, id: 1, end: {_id:0}, properties:{roles:["Trinity"]}}, {start: {_id:40}, id: 2, end: {_id:0}, properties:{roles:["Morpheus"]}}, {start: {_id:41}, id: 3, end: {_id:0}, properties:{roles:["Agent Smith"]}}, {start: {_id:45}, id: 4, end: {_id:0}, properties:{roles:["Emil"]}}, {start: {_id:38}, id: 5, end: {_id:1}, properties:{roles:["Neo"]}}, {start: {_id:39}, id: 6, end: {_id:1}, properties:{roles:["Trinity"]}}, {start: {_id:40}, id: 7, end: {_id:1}, properties:{roles:["Morpheus"]}}, {start: {_id:41}, id: 8, end: {_id:1}, properties:{roles:["Agent Smith"]}}, {start: {_id:38}, id: 9, end: {_id:2}, properties:{roles:["Neo"]}}, {start: {_id:39}, id: 10, end: {_id:2}, properties:{roles:["Trinity"]}}, {start: {_id:40}, id: 11, end: {_id:2}, properties:{roles:["Morpheus"]}}, {start: {_id:41}, id: 12, end: {_id:2}, properties:{roles:["Agent Smith"]}}, {start: {_id:38}, id: 13, end: {_id:3}, properties:{roles:["Kevin Lomax"]}}, {start: {_id:46}, id: 14, end: {_id:3}, properties:{roles:["Mary Ann Lomax"]}}, {start: {_id:47}, id: 15, end: {_id:3}, properties:{roles:["John Milton"]}}, {start: {_id:49}, id: 16, end: {_id:4}, properties:{roles:["Lt. Daniel Kaffee"]}}, {start: {_id:50}, id: 17, end: {_id:4}, properties:{roles:["Col. Nathan R. Jessup"]}}, {start: {_id:51}, id: 18, end: {_id:4}, properties:{roles:["Lt. Cdr. JoAnne Galloway"]}}, {start: {_id:52}, id: 19, end: {_id:4}, properties:{roles:["Capt. Jack Ross"]}}] AS row |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to PR, but shouldn't this file be in test/resources?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, probably. I can try to move it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like it is potentially used from extended so I don't think it is worth the risk to move it
core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java
Outdated
Show resolved
Hide resolved
return artificialUniques; | ||
} | ||
|
||
private long countArtificialUniqueRels(Relationship rel) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method can also be a single return.
if (!CypherFormatterUtils.isUniqueRelationship(rel)) { | ||
artificialUniques++; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not unique we increase number of uniques?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is what I was confused about in our Slack channel here: https://neo4j.slack.com/archives/C032XMUBAHG/p1716906509842369. The Cypher query we build up will add the UNIQUE IMPORT ID REL
to all relationships which are not already unique, and we want to calculate how many that will be (i.e. how many we make unique artificially), thus the inversion. This info is then used to know how many batches of deletion we need. Does that make sense? I can add a code comment trying to explain this as we both got confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still a bit confusing, but if you feel confident I'm happy :).
core/src/main/java/apoc/export/cypher/MultiStatementCypherSubGraphExporter.java
Outdated
Show resolved
Hide resolved
…raphExporter.java Co-authored-by: Love Kristofer Leifland <love.leifland@neotechnology.com>
9496e29
to
31aaf84
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Fixes #631
The bug was only affecting users who have set the
multipleRelationshipsWithType
configuration option to true.