Cypher Order by Path Cost

2019-03-22 09:04发布

I am extremely new to cypher and neo4j. I am wanting to get and order all paths between point A and B, based upon the total path cost. The cost in this case is a relationship property that is an integer. The path cost would be a summation of the relationship properties.

I am looking at some examples of cypher's ORDER BY statement however, by the examples, it seems that you have to order by a property that is already assigned to the object being ordered, in this case that won't work because paths do not have a static "cost" property.

(This is different from the lengths/number of paths btw)

I am pretty sure things like this are not too complicated for cypher.

标签: neo4j cypher
2条回答
劫难
2楼-- · 2019-03-22 10:00

I tried and failed to do something very similar to this a few days ago. The problem lies in the fact that you can't get a sum of a collection, only the sum of an aggregation.

See: https://groups.google.com/d/topic/neo4j/_MqwGp1a1Oo/discussion

I hope they'll add some functionality for this in Cypher, but I couldn't get it to work, even with the help of the expert--Michael Hunger.

UPDATE I actually poked at the Cypher code today to make an expression that does exactly this. I'm not sure if it will be accepted by 1.9, but maybe some form of it will get into the community edition soon.

UPDATE 2 They've merged in my pull request for reduce into 1.9-SNAPSHOT, I'll update the syntax below.

It does basically exactly what you're asking for--a slightly stale version of my data is here: http://console.neo4j.org/r/2rvznu

And here's the Cypher (NOTE, currently requires 1.9-SNAPSHOT):

   START n=node(18) 
   MATCH p=n-[r*]->m 
   WHERE not(m-->()) 
    WITH extract(x in r: x.score) as scores, length(p) as len
  RETURN scores, reduce(res=0, x in scores: res + x) as totalscore, len 
ORDER BY totalscore desc;

gives:

+------------------------------------------+
| scores        | totalscore         | len |
+------------------------------------------+
| [0.9,0.9,3.7] | 5.5                | 3   |
| [0.8,0.79]    | 1.59               | 2   |
| [0.4,0.75]    | 1.15               | 2   |
| [0.4,0.45]    | 0.8500000000000001 | 2   |
+------------------------------------------+
查看更多
手持菜刀,她持情操
3楼-- · 2019-03-22 10:06

For the convenience of everyone googling for this question, I updated the answer of @eve-freeman to Neo4j 3.0

START n=node(18) 
   MATCH p=(n)-[r*]->(m) 
   WHERE not((m)-->()) 
    WITH extract(x in r| x.score) as scores, length(p) as len
  RETURN scores, reduce(res=0, x in scores| res + x) as totalscore, len 
ORDER BY totalscore desc;

The differences are: Parentheses are required to identify nodes in patterns Pipe | instead of colon : is used to seperate "variable in list" and expression in functions

查看更多
登录 后发表回答