简体   繁体   中英

Neo4j Cypher query sort order

In my Neo4j/SDN project I have a following mode:

Decision entity that contains child Decision and Characteristic entities.

Each pair of child Decision and Characteristic can have a Value node assigned.

I have created 3 child Decision nodes, for example

childDecision1
childDecision2
childDecision3

and one Characteristic :

characterisitc1

I have assigned following values to the following pairs:

childDecision2 + characterisitc1 = Value(Integer 10)
childDecision3 + characterisitc1 = Value(Integer 25)

I'm executing the following Cypher query(with O RDER BY sortValue88.value ASC ):

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId} 
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue88:Value)-[:SET_ON]->(sortCharacteristic88:Characteristic) 
WHERE id(sortCharacteristic88) = 88
WITH ru, u, childD , sortValue88 
ORDER BY sortValue88.value ASC SKIP 0 LIMIT 100 
RETURN ru, u, childD AS decision, [ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) | {entityId: id(entity),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, [ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) | {criterionId: id(c1),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, [ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) | {characteristicId: id(ch1),  value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

As the result I have:

childDecision2 (Value = 10)
childDecision3 (Value = 25)
childDecision1 (no value provided)

So far everything works fine.

Right now I'm going to change the sort order direction from ASC to DESC :

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId}
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue88:Value)-[:SET_ON]->(sortCharacteristic88:Characteristic) 
WHERE id(sortCharacteristic88) = 88
WITH ru, u, childD , sortValue88 
ORDER BY sortValue88.value DESC SKIP 0 LIMIT 100 
RETURN ru, u, childD AS decision, [ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) | {entityId: id(entity),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, [ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) | {criterionId: id(c1),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, [ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) | {characteristicId: id(ch1),  value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

As the result I have:

childDecision1 (no value provided)
childDecision3 (Value = 25)
childDecision2 (Value = 10)

Right now I don't understand why the childDecision1 hold the first place but I expect childDecision3 instead there.

Could you please help to explain/fix this behavior ?

Because: When sorting the result set, null will always come at the end of the result set for ascending sorting, and first when doing descending sort.

So you need to know the minimum possible value for sorting. For example, if all values are not less than zero

WITH [1, 0, 2, NULL, 4] AS CS
UNWIND RANGE(0, size(CS)-1) as i
RETURN i, 
       CASE WHEN CS[i] IS NULL THEN -1 ELSE CS[i] END AS sortValue
ORDER BY sortValue DESC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM