PrasoonMishra
PrasoonMishra

Reputation: 83

Cypher match for collection having multiple properties

I have created 4 nodes in neo4j having name and skills as their properties .How to find nodes having one or more similar skills using CQL .

CREATE 
(c1:Person {name:'a',skills:['Java','Apache Hadoop','Apache Storm','Apache Solr','Hbase','Map-reduce','Spring']}),
(c2:Person {name:'b',skills:['Java','HTML5','LifeRay','MYSQL']}),
(c3:Person {name:'c',skills:['HTML5','LifeRay','MYSQL']}),
(c4:Person {name:'d',skills:['Java','Apache Hadoop','Apache Storm','Apache Solr','Hbase','Map-reduce']});

Upvotes: 0

Views: 207

Answers (1)

Stefan Armbruster
Stefan Armbruster

Reputation: 39915

You should refactor your data model here. Your use case is "Find people sharing the same skill" - so skill is a "thing" in your domain, therefore it should be a node instead of hiding the information in a property. A person having a skill is connected via a HAS_SKILL relationship to that node.

Refactoring your graph can be done with that one:

match (p:Person)
foreach (s in p.skills | 
    merge (skill:Skill {name:s}) 
    merge (p)-[:HAS_SKILL]->(skill) 
)
remove p.skills

Based on the new model, the query for people with similar skills is simple:

match (p1:Person)-[:HAS_SKILL]->(s:Skill)<-[:HAS_SKILL]-(p2:Person)
where id(p1)<id(p2)
return p1.name, p2.name, s.name

The where condition is used to prevent duplicate results caused by p1 and p2 changing roles within the traversion.

Upvotes: 1

Related Questions