Perhaps you could consider writing an Evaluator instead of an Expander,
which allows you more fine grained control over what you want to do at each
step. See for example the search evaluator at
https://github.com/neo4j-contrib/spatial/blob/master/src/main/java/org/neo4j/gis/spatial/rtree/RTreeIndex.java#L269

This allows you to return one of the four conditions:

   - Evaluation.EXCLUDE_AND_CONTINUE
   - Evaluation.EXCLUDE_AND_PRUNE
   - Evaluation.INCLUDE_AND_CONTINUE
   - Evaluation.INCLUDE_AND_PRUNE



On Tue, Dec 27, 2016 at 11:23 AM, Aviran Katz <[email protected]> wrote:

> 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]> 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].
>>> 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.
>

-- 
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