SDN4/OGM Cypher query and duplicates at Result

2019-06-01 14:30发布

问题:

I have a following Cypher query:

MATCH (parentD)-[:CONTAINS]->(childD:Decision) 
WHERE parentD.id = 1 
OPTIONAL MATCH (childD)-[sortValue1:HAS_VALUE_ON]->(sortCharacteristic1:Characteristic) 
WHERE sortCharacteristic1.id = 1 
WITH * MATCH (childD)-[ru:CREATED_BY]->(u:User) 
OPTIONAL MATCH (childD)-[rup:UPDATED_BY]->(up:User)  
WITH ru, u, rup, up, childD , sortValue1 
ORDER BY sortValue1.value ASC SKIP 0 LIMIT 100 
RETURN ru, u, rup, up, childD AS decision, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
  | {entityId: toInt(entity.id),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD) 
  | {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[v1:HAS_VALUE_ON]-(childD)  WHERE NOT ((ch1)<-[:DEPENDS_ON]-())  
  | {characteristicId: toInt(ch1.id),  value: v1.value, available: v1.available, totalHistoryValues: toInt(v1.totalHistoryValues), description: v1.description, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

which correctly returns 3 Decision:

I have introduced a new node Tag and associated it with Decision in a following manner:

(d:Decision)-[rdt:BELONGS_TO]->(t:Tag)

I have updated the first query in order to return Decision with Tags:

MATCH (parentD)-[:CONTAINS]->(childD:Decision) 
WHERE parentD.id = 1 
OPTIONAL MATCH (childD)-[sortValue1:HAS_VALUE_ON]->(sortCharacteristic1:Characteristic) 
WHERE sortCharacteristic1.id = 1 
WITH * 
MATCH (childD)-[ru:CREATED_BY]->(u:User) 
OPTIONAL MATCH (childD)-[rup:UPDATED_BY]->(up:User) 
OPTIONAL MATCH (childD)-[rdt:BELONGS_TO]->(t:Tag)  
WITH ru, u, rup, up, rdt, t, childD , sortValue1 
ORDER BY sortValue1.value ASC SKIP 0 LIMIT 100 
RETURN ru, u, rup, up, rdt, t, childD AS decision, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
  | {entityId: toInt(entity.id),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD) 
  | {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[v1:HAS_VALUE_ON]-(childD)  WHERE NOT ((ch1)<-[:DEPENDS_ON]-())  
  | {characteristicId: toInt(ch1.id),  value: v1.value, available: v1.available, totalHistoryValues: toInt(v1.totalHistoryValues), description: v1.description, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

I have added 2 Tag to Neo4j decision.

The query works fine and correctly returns the same 3 decisions where Neo4j contains 2 Tag:

but I ran into the following issue - I use SDN4/OGM in order to convert a query Result to my model:

Result result = session.query(cypherQuery.toString(), parameters); 

for (Map<String, Object> result : queryResult) {
    Decision decision = (Decision) result.get("decision");
}

and instead of having 3 Decision - Result contains 4 Decision:

Redis(null tags)
MongoDB(null tags)
Neo4j(tag1 and tag 2)
Neo4j(tag1 and tag 2)

as you can see - the result contains the same Neo4j decision two time.

What am I doing wrong and how to tell OGM/SDN 4 to place Neo4j(tag1 and tag 2) only one time in the result set ?

By the way - I have added OPTIONAL MATCH (childD)-[rdt:BELONGS_TO]->(t:Tag) in order to initialize Tag within Decision. If it can be done in some other way - please let me know also.

UPDATED

I have created a Neo4j Sandbox to test the mentioned queries:

http://52.87.220.140:33853/browser/
Username: neo4j
Password: idea-chocks-payroll

I have debugged the OGM/Neo4j internals. The following data comes with org.neo4j.graphdb.Result:

(scala.collection.convert.Wrappers$MapWrapper<A,B>) {rup=null, commentGroups=[], up=null, t=Node[6677], u=Node[6667], decision=Node[6678], weightedCriteria=[], ru=(6678)-[CREATED_BY,22875]->(6667), valuedCharacteristics=[], rdt=(6678)-[BELONGS_TO,22876]->(6677)}

(scala.collection.convert.Wrappers$MapWrapper<A,B>) {rup=null, commentGroups=[], up=null, t=Node[6676], u=Node[6667], decision=Node[6678], weightedCriteria=[], ru=(6678)-[CREATED_BY,22875]->(6667), valuedCharacteristics=[], rdt=(6678)-[BELONGS_TO,22877]->(6676)}

(scala.collection.convert.Wrappers$MapWrapper<A,B>) {rup=null, commentGroups=[], up=null, t=null, u=Node[6667], decision=Node[6684], weightedCriteria=[], ru=(6684)-[CREATED_BY,22895]->(6667), valuedCharacteristics=[{totalHistoryValues=0, description=null, valueType=INTEGER, characteristicId=1, available=null, visualMode=INTEGERRANGESLIDER, value=25}], rdt=null}

(scala.collection.convert.Wrappers$MapWrapper<A,B>) {rup=null, commentGroups=[], up=null, t=null, u=Node[6667], decision=Node[6681], weightedCriteria=[], ru=(6681)-[CREATED_BY,22886]->(6667), valuedCharacteristics=[{totalHistoryValues=0, description=Integer value, valueType=INTEGER, characteristicId=1, available=true, visualMode=INTEGERRANGESLIDER, value=10}], rdt=null}

There are 4 Objects(rows) at the org.neo4j.graphdb.Result model..

Do I need to handle duplicates at my application code or it is possible to change Cypher query or SDN4/OGM in order to prevent duplicates at the Result ? Ideally I need a single row with decision=Node[6678] and 2 Tag inside(t=Node[6676] and t=Node[6677]) instead of a 2 different rows.

For example, is it possible to change the following Cypher RETURN statement in order to place tags(t) inside decision: RETURN ru, u, rup, up, rdt, t, childD AS decision instead of having both of them at the same level ?