Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get all the hops in a path of unknown length with neo4j-python?

Tags:

python

neo4j

MATCH (u:User {name: $user}), (target:Group {name: $group}), p=shortestPath((u)-[*]->(target)) RETURN p

When I run the above query in the Neo4j web UI, a fell graph of the resulting paths is displayed.

However, when I run the same query with the neo4j-python driver, only a Path objects with limited information are returned

<Path start=479557 end=404582 size=1>

How can I use Cypher and python to get complete path details, including all nodes and the relationships that connect them?

like image 723
Sean W. Avatar asked Feb 25 '17 12:02

Sean W.


People also ask

How do I return all nodes and relationships in Neo4j?

When you want to return all nodes, relationships and paths found in a query, you can use the * symbol. This returns the two nodes, the relationship and the path used in the query.

Why would you use Neo4j match?

The MATCH clause allows you to specify the patterns Neo4j will search for in the database. This is the primary way of getting data into the current set of bindings. It is worth reading up more on the specification of the patterns themselves in Patterns.

When you create a relationship in Cypher You must specify a direction True or false?

Syntax: Creating relationships When you create the relationship, it must have direction. You can query nodes for a relationship in either direction, but you must create the relationship with a direction.


2 Answers

Depends on how you want to return data, but you can try something like this

MATCH (u:User {name: $user}), (target:Group {name: $group}),
p=shortestPath((u)-[*]->(target)) RETURN nodes(p),relationships(p)
like image 67
Tomaž Bratanič Avatar answered Sep 28 '22 15:09

Tomaž Bratanič


Thanks for the help everyone! For reference, here's my complete example that converts paths to human-readable strings for console or email output.

def find_paths_from_standard_user_to_domain_admins(standard_user, domain_admins_group):
    """Returns a list of paths that a standard user could take to get domain admin credentials"""
    results = []
    query = "MATCH (u:User {name:{user}}), (target:Group {name: {group}})," \
            "p=allShortestPaths((u)-[*]->(target)) RETURN p"
    with driver.session() as session:
        with session.begin_transaction() as tx:
            for record in tx.run(query, user=standard_user, group=domain_admins_group):
                relationships = record["p"].relationships
                nodes = record["p"].nodes
                path = ""
                for i in (range(len(relationships))):
                    path += "{0}-[{1}]->".format(nodes[i]["name"], relationships[i].type)
                path += nodes[-1]["name"]
                results.append(path)
    return results

This is a query for a graph generated by the Bloodhound project, which builds graphs of Active Directory structures. It's extremely useful for domain admins, system architects, network defenders, and pentesters.

like image 35
Sean W. Avatar answered Sep 28 '22 15:09

Sean W.