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 ?