Search code examples
neo4jcyphersimilarity

Cypher - match nodes with similar relations rank result based on number of identical relations


I have a graph where node/relations look like:

(n:Entity)-[r:HasAttribute]->(a:Attribute)

All Entity- and Attibute-nodes have a property called id_obj to identify each node Lets say I have an Entity with id_obj '111' (n:Entity {id_obj:'111'}) and wants to find all other Entity-nodes that has same Attributes as Entity-111 i.e find them having the same Attribute-nodes with same id_obj and rank the result (other Entity nodes) based on the number of same Attribute-nodes.... How do I do that?

I have been looking at: https://neo4j.com/docs/graph-data-science/current/algorithms/alpha/filtered-node-similarity/ but I cant figure out how I can start with one start node (Entity-111) and compare all others. In examples on page it seems like you comparing all nodes and rank them

Thanks!


Solution

  • You can filter the source node(s) by specifying on the sourceNodeFilter configuration parameter. The sourceNodeFilter can be a single node id (or a list of node ids) or single node (or a list of nodes) or a label.

    In my example below, I will filter only 'Alice' in line #1 and call it alice.

    MATCH (alice:Person) where alice.name = 'Alice'
    CALL gds.alpha.nodeSimilarity.filtered.stream('myGraph', {sourceNodeFilter: alice, targetNodeFilter:'Singer' } )
    YIELD node1, node2, similarity
    RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
    ORDER BY similarity DESCENDING, Person1, Person2
    

    Result:

    ╒═════════╤═════════╤══════════════════╕
    │"Person1"│"Person2"│"similarity"      │
    ╞═════════╪═════════╪══════════════════╡
    │"Alice"  │"Bob"    │0.6666666666666666│
    ├─────────┼─────────┼──────────────────┤
    │"Alice"  │"Carol"  │0.3333333333333333│
    └─────────┴─────────┴──────────────────┘
    

    Thus, in your example;

     MATCH (n:Entity {id_obj:'111'}) 
     CALL gds.alpha.nodeSimilarity.filtered.stream('yourGraph', {sourceNodeFilter: n, targetNodeFilter:'Entity' } )
     and so on...
    

    Reference: https://neo4j.com/docs/graph-data-science/current/algorithms/alpha/filtered-node-similarity/#algorithms-filtered-node-similarity-filter-configuration