2

Assume My Graph is having the below paths

      (3)<--[IS_LOCATED_AT,9]--(8)--[CARRIES,77]-->(53)<--[CARRIES,76]--(7)--[IS_LOCATED_AT,8]-->(2)
      (3)<--[IS_LOCATED_AT,9]--(8)--[BELONGS_TO,7]-->(1)<--[BELONGS_TO,6]--(7)--[IS_LOCATED_AT,8]-->(2)
      (3)<--[IS_LOCATED_AT,9]--(8)--[BELONGS_TO,7]-->(55)<--[BELONGS_TO,61]--(7)--[IS_LOCATED_AT,8]-->(2)
      (3)<--[IS_LOCATED_AT,9]--(8)--[CARRIES,77]-->(57)<--[CARRIES,75]--(7)--[IS_LOCATED_AT,8]-->(2)

Assume paths having the below mentioned properties

     (53) node has the properties--{Name:A}

     (1) node has properties--{Name:B}

     (55) node has properties--{Name:C}

     (57) node has properties-- {Name:D}

Assume If I call the shortestpath between nodes (3) and (2) , I am getting the below output when called the below mentioned method.

assume current Output is:

        (3)<--[IS_LOCATED_AT,9]--(8)--[BELONGS_TO,7]-->(1)<--[BELONGS_TO,6]--(7)--[IS_LOCATED_AT,8]-->(2)
        (3)<--[IS_LOCATED_AT,9]--(8)--[BELONGS_TO,7]-->(55)<--[BELONGS_TO,61]--(7)--[IS_LOCATED_AT,8]-->(2)

But My requirement is 1)It should filter the paths based on node property before calling the shortestpath api assume my filter is {Name:D} which is a property of (57) node mentioned above

Then My output should be as below when called shortespath method menntioned below as the below path having node (57) having property {Name:D} .

Expected Output with filter

          (3)<--[IS_LOCATED_AT,9]--(8)--[CARRIES,77]-->(57)<--[CARRIES,75]--(7)--[IS_LOCATED_AT,8]-->(2)

I dont want to use cypher for this. Can anybody help me.

         public static Iterable<Path> shortestPath(Node sourceNode, Node destNode)
         {
            Integer depth=100;
            PathExpander<?> expander;
            List<Path> paths = new ArrayList<>();
              if ( orderedRelTypes == null )
                {
                   expander = PathExpanders.allTypesAndDirections();
                }
             else
               {
                  PathExpanderBuilder expanderBuilder =   PathExpanderBuilder.empty();

                  expanderBuilder = expanderBuilder

                  .add(MyRelationshipTypes.BELONGS_TO, Direction.BOTH)
                  .add(MyRelationshipTypes.CARRIES, Direction.BOTH)
                  .add(MyRelationshipTypes.IS_LOCATED_AT, Direction.BOTH);

                  expander = expanderBuilder.build();

                 }
              try (Transaction tx = graphDb.beginTx()) {


             PathFinder<Path> shortestPath = GraphAlgoFactory.shortestPath(
               expander, depth == null ? 100 : depth.intValue());
               Iterable<Path> pathss = shortestPath.findAllPaths(sourceNode, destNode);

               for(Path path1:pathss){
               paths.add(path1);

        System.out.println("result::::"+paths);
              }

            tx.success();
           }
          return paths;
         }
   }
raj
  • 107
  • 2
  • 11
  • don't quite understand what the question really is here. – Stefan Armbruster Jun 26 '16 at 20:36
  • Thank you for your reply. I am trying to find the shortestpath between two nodes by applying predicate(based on Node property value filter ).can you give me the steps for this.can I acheive this with neo4j 3.0.1 java version. – raj Jun 27 '16 at 17:09
  • The code looks fine so far. Maybe adding a failing unit test with some sample data would explain better why the above doesn't behave as you intend. – Stefan Armbruster Jun 27 '16 at 20:29
  • I have got these two shortest paths.But my requirement is I need to add filter to these paths also based on one or more node property values using java API. Is there way I can add filter to GraphAlgoFactory.shortestPath api or you can give me the suggestions. PATH1:::: (3)<--[IS_LOCATED_AT,9]--(8)--[BELONGS_TO,7]-->(1)<--[BELONGS_TO,6]--(7)--[IS_LO‌​CATED_AT,8]-->(2) PATH2:::(3)<--[IS_LOCATED_AT,9]--(8)--[CARRIES,68]-->(51)<--[CARRIES,67]--(7)--[IS_LOCAT‌​ED_AT,8]-->(2) – raj Jun 28 '16 at 13:42
  • so a path is valid if each and every node along that path has the property with the defined value set? Or is the restriction that at least one node along that path needs to fulfill the criteria? – Stefan Armbruster Jun 28 '16 at 15:12
  • Thank you very much for your kind reply ,Stefan , it is the restriction that at least one node along that path needs to fulfill the criteria .One more question is it possible to put filter on Node before calling shortest path API? I mean it should filter the paths based on filter on node properties and then shortest path api should be called on the filtered paths. Is it possible.if yes suggestion please. – raj Jun 29 '16 at 14:20
  • sefan, kindly comment – raj Jun 30 '16 at 08:24
  • Use Cypher it's much easier, it will automatically pull in predicates into the shortest-path when possible. – Michael Hunger Jul 12 '16 at 07:37
  • Thanks Hunger for your reply,But our requirement is to use neo4j java api .not Cypher. – raj Jul 12 '16 at 09:13
  • Hi Hunger, Could you please help.I have updated question with more details.Waiting for your response.Thank in advance for your help – raj Jul 19 '16 at 09:13

1 Answers1

1

If the restriction applies to at least one node along the path (and not to every node) the snippet above will not work. The strategy to apply here would be as follows:

  1. use shortestPath.findAllPaths without filtering for the node property
  2. filter the shortest paths you've found in 1) if any of those contains a node with the given property. If yes: done, otherwise:
  3. use GraphAlgoFactory.pathsWithLength() and ask for paths of length+1 (where length is the length of the shortest paths from step 1)
  4. check if any of paths with length+1 fulfills the criteria (see 2). If not go back to 3 with length=length+1

An alternative way would be using GraphDatabaseService.bidirectionalTraversalDescription() and apply the property check within the collision evaluator. But I consider this approach way more complex than the strategy sketched above.

Stefan Armbruster
  • 39,465
  • 6
  • 87
  • 97
  • Thanks Stefan.My understanding is property check can be done before calling shortestPath.findAllPaths() provided using GraphDatabaseService.bidirectionalTraversalDescription(). Since this is complex, Would you please publish the sample code if you have. – raj Jun 30 '16 at 12:30
  • some examples are in the unit tests of Neo4j's source code: https://github.com/neo4j/neo4j/blob/3.1/community/kernel/src/test/java/org/neo4j/kernel/impl/traversal/TestBidirectionalTraversal.java – Stefan Armbruster Jun 30 '16 at 15:30
  • what is the use of addNodeFilter method from PathExpanderBuilder class – raj Jul 11 '16 at 09:28
  • we need to find the shortestpath between two nodes using node property filter using Neo4j 3.0.1 java version. What I mean is shortestpath api should filter the paths based on node filter property internally and among the filtered paths , it should find the shortest path. Is this possible?If yes would you please give us github link or some suggetions. Once again, Thank you for your help . – raj Jul 12 '16 at 05:22
  • from your verbal description it's almost impossible to understand the problem. Provide some sample data - preferably by sharing a setup via http://console.neo4j.org/ - and also the expected result. – Stefan Armbruster Jul 12 '16 at 20:52
  • MATCH path = allshortestPaths((a:Place { Name: 'Mysore' })<-[*] ->(b:Place { Name: 'Bangalore' })) WHERE ANY(x IN nodes(path) WHERE x.Type = "Geographic") RETURN path. Instead of cypher, I want to achive the same using neo4j java api.I am not able to achive this using nodeFilter used in the above program.Can you give some suggestions. – raj Jul 18 '16 at 08:23
  • Hi Stefan, Could you please help.I have updated question with more details.Waiting for your response – raj Jul 19 '16 at 09:12