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.

Reply via email to