Neo4j Match Node Property OR Relationship Property

北慕城南 提交于 2019-12-06 12:40:01

问题


I'm trying to write a query that will return nodes that either match a node property or a relationship property.

For instance, I want all nodes where the name property is George OR if the relationship property status is "good". I have two queries that will get the nodes for each of these:

MATCH (n) where n.name = 'George' return n

MATCH (n)-[r]-() where r.status = 'good' return n 

Is there a singe query I could write to get these combined results? I thought I could use this optional query (below), but I seemed to have misunderstood the optional match clause because I'm only getting nodes from the first query.

MATCH (n) where n.name = 'George' 
Optional MATCH (n)-[r]-() where r.status = 'good' return distinct n 

回答1:


By the time the optional match happens, the only n nodes that are around to make the optional match from are the ones that already match the first criteria. You can do

MATCH (n)
WHERE n.name = 'George' OR n-[{ status:"good" }]->()
RETURN n

but for larger graphs remember that this will not make efficient use of indices.

Another way would be

MATCH (n {name:"George"})
RETURN n
UNION MATCH (n)-[{status:"good"})->()
RETURN n

This should do better with indices for the first match, assuming you use a label and have the relevant index set up (but the second part would still potentially be very inefficient).

Edit
Re comment, relationship indexing would make that part faster, correct, but to my mind it would be better to say it is slow because the pattern is underdetermined. The second match pattern does something like

  • bind every node in the graph to (n)
  • get all outgoing relationships (regardless of type) from (n)
  • check relationship for status="good"

You could improve performance with relationship indexing, but since a relationship exists only between the two nodes it relates, you can think of it instead as indexed by those nodes. That is, fix the first bullet point by excluding nodes whose relationships are not relevant. The two match clauses could look like

MATCH (n:Person {name:"George"})  
       // add label to use index
MATCH (n:Person)-[{status:"good"}]->() 
       // add label to limit (n) -no indexing, but better than unlimited (n)
MATCH (n:Person {name:"Curious"})-[{status:"good"}]->()
       // add label to use index -now the relationships are sort-of-indexed

and/or type the relationship

MATCH (n)-[:REL {status:"good"}]->() // add type to speed up relationship retrieval

in fact, with anonymous relationships and rel property, it would probably make sense (bullet point three) to make the property the type, so

MATCH (n)-[:GOOD]->() // absent type, it would make sense to use the property as type instead

Your actual queries may look very different, and your question wasn't really about query performance at all :) oh well.



来源:https://stackoverflow.com/questions/22949573/neo4j-match-node-property-or-relationship-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!