2
votes

I am completely new to Neo4j. I am testing the graph database and I have the following simple graph test-structure: different labeled nodes with properties, which are connected.

All the nodes have a property, which is called access. It is a list of string elements such as:

{access: ['http', 'www']}

I'm searching for a solution, where I get all nodes from a starting node which are connected (doesn't matter which type or direction) and their relationship where an intersection on the access property of the nodes exists. I will start at a given node and compare the access property with the next connected node. Then, take the property of the second node and compare this access property with the nodes, which are connected to them. And so on. The goal should be all nodes and their connections, where an interesection on access property exists. On the concrete structure of the graph, for example, we start at the node ENC 2009 and should traverse all connected nodes until a node with no intersection on the access property is reached. For this example, the following goal should be reached: traversed graph

I tried the following cypher query, but it is not working fine on each node as starting node.

MATCH (n:CONFERENCE_SERIE) WHERE n.full_name =~ 'mex.*'
MATCH p = n-[*]-m WHERE FILTER(x IN n.access WHERE x IN m.access)
RETURN p

Is there a solution, with the java traversal framework or with cypher, to reach the goal and to get the path of such an graph?

Thanks in advance for your help.

2
Are you looking for a path where all nodes have at least one access property in common? Or do you look for an intersection at each individual step, i.e. the first and last node do not need an intersection? Does the size of the intersection matter?Martin Preusse
I am searching for an intersection at each individual step. So for example, that a specific conference series could access the conference instances and the presented paper, but not the author who wrote the paper or the journal. The size of the intersection doesn't matter. At least one match of an element in the access list means, that node has access and could be added to the path.h.bisch

2 Answers

1
votes

OK, I found a solution, which works for me. @MichaelHunger, thanks for your hints. I hope it is also fine for my colleague which are working with the graph information. We will see it tomorrow.

Just for information: in the traversalDescription, I created an Evaluator. I took the last relationship from the path and take the property access from the start- and the end-node. Now I can compare if there is a intersection between both properties. If so, I include the node to the result and continue. If not, exclude the node and stop the traversal. It works and I hope it is an efficient solution.

The source code looks like:

        TraversalDescription traversal = db.traversalDescription().depthFirst().evaluator(new Evaluator() {
        @Override
        public Evaluation evaluate(Path path) {
            // TODO Auto-generated method stub
            if (path.length() != 0) {
                String[] startAccess = (String[]) path.lastRelationship().getStartNode().getProperty("access");
                String[] endAccess = (String[]) path.lastRelationship().getEndNode().getProperty("access");

                if (checkInteresection(startAccess, endAccess)) {
                    return Evaluation.INCLUDE_AND_CONTINUE;
                } else {
                    return Evaluation.EXCLUDE_AND_PRUNE;
                }
            }
            return Evaluation.INCLUDE_AND_CONTINUE;
        }
1
votes

The java traversal framework will be more efficient at this, you would use the relationships of the current Path in your RelationshipExpander

http://neo4j.com/docs/stable/tutorial-traversal-java-api.html#_pathexpander_relationshipexpander

In cypher you could do something like:

MATCH (n:CONFERENCE_SERIE) WHERE n.full_name =~ 'mex.*'
MATCH p = n-[*]-m 
WHERE FILTER(idx IN range(0,length(p)-2) 
      WHERE ANY(access IN (rels(p)[idx]).access 
                WHERE access IN (rels(p)[idx+1]).access))
RETURN p

i.e. have an counter go from 0 to path-len-2 look at each pair of rels of the path and check that at least one (ANY) access code is contained in the next rel's access-property.