Thank you, that helped :)

Another thing - I noticed that - after implementing the node filter 
correctly - a path is not expanded when an invalid node is reached. This 
means that my problem remains, as paths with a single invalid node will 
return. I want all paths which contain at least one invalid node to be 
disqualified.

In other words, not expanding an invalid node is not good enough. What I 
need is a *PathExpande*r that disqualifies a path the moment an invalid 
node is reached. Is this achievable?

On Sunday, December 25, 2016 at 8:13:03 PM UTC+2, Craig Taverner wrote:
>
> The method 'addNodeFilter' returns the modified builder, which should take 
> into account node filtering. Your code appears to not used the modified 
> builder, but instead the original builder.
>
> I took a peek at the code for addNodeFilter to verify this use of the 
> builder pattern: 
> https://github.com/neo4j/neo4j/blob/3.2/community/graphdb-api/src/main/java/org/neo4j/graphdb/PathExpanderBuilder.java#L132
>
> On Thu, Dec 22, 2016 at 12:39 PM, Aviran Katz <[email protected] 
> <javascript:>> wrote:
>
>> Hi all,
>> I'm trying to write a procedure that uses Dijkstra's algorithm to find 
>> the shortest weighted path between two nodes. All nodes in that path should 
>> have specific properties and values, otherwise the path is invalid, and the 
>> algorithm should continue searching for the next shortest weighted path.
>> I'm trying to tackle this using PathExpanderBuilder.addNodeFilter, as 
>> follows:
>>
>> PathExpanderBuilder builder = PathExpanderBuilder.allTypesAndDirections();
>> builder.addNodeFilter(
>>         node -> !node.hasProperty(prop1) ||
>>                 node.getProperty(prop1) instanceof Long &&
>>                         (long) node.getProperty(prop1) < prop1Value
>> );
>>
>>
>>  When I run the procedure, the filter doesn't take action, and invalid 
>> paths end up returning in the query result.
>> Below is my full procedure code:
>>
>> public class Demo {
>>     @Procedure
>>     @Description("apoc.algo.multiDijkstraWithDefaultWeight(startNode, 
>> endNode, " +
>>             "'distance', 10, 'prop1', 2, 'prop2', [100, 200], 'prop3') " +
>>             " YIELD path, weight - run dijkstra with relationship property 
>> name as cost function" +
>>             " and a default weight if the property does not exist")
>>     public Stream<WeightedPathResult> multiDijkstraWithDefaultWeight(
>>             @Name("startNode") Node startNode,
>>             @Name("endNode") Node endNode,
>>             @Name("weightPropertyName") String weightPropertyName,
>>             @Name("defaultWeight") double defaultWeight,
>>             @Name("longPropName") String longPropName,
>>             @Name("longPropValue") long longPropValue,
>>             @Name("listPropName") String listPropName,
>>             @Name("listPropValues") List<Long> listPropValues,
>>             @Name("boolPropName") String boolPropName) {
>>
>>         PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra(
>>                 buildPathExpanderByPermissions(longPropName, longPropValue, 
>> listPropName, listPropValues, boolPropName),
>>                 (relationship, direction) -> 
>> convertToDouble(relationship.getProperty(weightPropertyName, defaultWeight))
>>         );
>>         return WeightedPathResult.streamWeightedPathResult(startNode, 
>> endNode, algo);
>>     }
>>
>>     private double convertToDouble(Object property) {
>>         if (property instanceof Double)
>>             return (double) property;
>>         else if (property instanceof Long)
>>             return ((Long) property).doubleValue();
>>         else if (property instanceof Integer)
>>             return ((Integer) property).doubleValue();
>>         return 1;
>>     }
>>
>>     private PathExpander<Object> buildPathExpanderByPermissions(
>>             String longPropName,
>>             long longPropValue,
>>             String listPropName,
>>             List<Long> listPropValues,
>>             String boolPropName
>>     ) {
>>         PathExpanderBuilder builder = 
>> PathExpanderBuilder.allTypesAndDirections();
>>         builder.addNodeFilter(
>>                 node -> !node.hasProperty(longPropName) ||
>>                         node.getProperty(longPropName) instanceof Long &&
>>                                 (long) node.getProperty(longPropName) < 
>> longPropValue
>>         );
>>         builder.addNodeFilter(
>>                 node -> {
>>                     try {
>>                         return !node.hasProperty(listPropName) ||
>>                                 (boolean) node.getProperty(boolPropName, 
>> false) ||
>>                                 !Collections.disjoint((List<Long>) 
>> node.getProperty(listPropName), listPropValues);
>>                     }
>>                     catch (Exception e){
>>                         return false;
>>                     }
>>                 }
>>         );
>>         return builder.build();
>>     }
>> }
>>
>>
>> Your help is greatly appreciated.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Neo4j" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to