PathExpanderBuilder.addNodeFilter 是如何运作的?

How does PathExpanderBuilder.addNodeFilter work?

我正在研究一个程序,该程序应该使用 Dijkstra 算法找到两个节点之间的最低权重路径。该过程应该只有 return 个所有节点都符合特定条件的路径(即所有节点都应该具有具有特定值的属性)。如果路径中至少有一个节点不符合条件,则该路径无效,算法应寻找下一个权重最低的路径。

为了实现这一点,我使用了带有节点过滤器的 PathExpanderBuilder,但它们似乎没有过滤任何东西。

这是我的代码:

public class Demo {
    @Procedure
    @Description("apoc.algo.dijkstraWithFilters(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> dijkstraWithFilters(
            @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> listPropValue,
            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), listPropValue);
                    }
                    catch (Exception e){
                        return false;
                    }
                }
        );
        return builder.build();
    }
}

我在这里错过了什么?我是否错误地使用了 PathExpanderBuilder

PathExpanderBuilder 是不可变的,因此调用例如addNodeFilter returns 添加过滤器的新 PathExpanderBuilder,因此您需要使用返回的实例重新分配 builder