I think instead of evaluating the whole path over and over again, use the information that the path up until the currentl point already conforms to the specification and rather use a RelationshipExpander/PathExpander, to select the next relationships that fulfill that condition:
" if a edge "r" has r.property in [1,10] and r.property = x the next edge "r1", of the path, must have r1.property in [x,10] and so on. " I'd also use primitive longs for start and end to avoid boxing. Is the measured run the first run of your path finding or a subsequent run? Michael On Sun, May 18, 2014 at 11:57 PM, Andrea Santurbano <[email protected]>wrote: > Hi guys, > with my colleagues we are comparing two graph databases wich one is neo4j. > We have around 100k of nodes and 1m of edges and we need traverse the > graph by a start node. > While in other db we have no difficult to get the results in few seconds, > in neo4j we get several performance issue. > > Our problem: > Given a start node are considered valid all paths that satisfy a condition: > Given a range [1, 10] > if a edge "r" has r.property in [1,10] and r.property = x the next edge > "r1", of the path, must have r1.property in [x,10] and so on... > > For small ranges the performance of two dbs are comparable... > > We use the traversal api: > > private Traverser getFoF(final Node node, boolean isBackward, > Long start, Long end) { > TraversalDescription td = graphDb > .traversalDescription() > .order(BranchOrderingPolicies.PREORDER_DEPTH_FIRST) > .relationships(RelTypes.MOVES, Direction.OUTGOING) > .evaluator(Evaluators.excludeStartPosition()) > .uniqueness(Uniqueness.RELATIONSHIP_PATH) > .evaluator(new PathFilter(start, end)); > return td.traverse(node); > } > > public class PathFilter implements Evaluator, Predicate { > Long lastValue = 0L > , start = 0L > , end = 0L; > public PathFilter(Long start, Long end) { > this.start = start; > this.end = end; > } > @SuppressWarnings("unchecked") > public Evaluation evaluate(Path path) { > List<Relationship> filteredRels = (List<Relationship>) > CollectionUtils.select(IteratorUtils.toList(path.relationships().iterator()), > new PathFilter(start, end)); > if (path.length() == filteredRels.size()) { > return Evaluation.INCLUDE_AND_CONTINUE; > } > return Evaluation.EXCLUDE_AND_PRUNE; > } > public boolean evaluate(Object arg) { > if (!(arg instanceof Relationship)) { > return false; > } > if (lastValue == 0L) { > lastValue = start; > } > Relationship rel = (Relationship) arg; > Long property = (Long) rel.getProperty("property"); > if (evaluateDate(property, lastValue, end)) { > lastValue = property; > return true; > } > return false; > } > private boolean evaluateDate(Long value, Long start, Long end) { > return value >= start && value <= end; > } > } > > Another request: > exists already a construct that allows cypher to make an assessment of > this type? > Thanks to all > > -- > 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.
