Sorry, it should be: for ( Node currentNode : Traversal.description() .breadthFirst().uniqueness( Uniqueness.RELATIONSHIP_GLOBAL) .relationships(MyRelationships.SIMILAR) .relationships(MyRelationships.CATEGORY) .prune(TraversalFactory.pruneAfterDepth(2)).traverse(node) ) {
2010/7/9 Mattias Persson <matt...@neotechnology.com> > Just to notify you guys on this... since as of now (r4717) the > TraversalFactory class is named Traversal instead, so code would look like: > > for ( Node currentNode : TraversalFactory.description() > > .breadthFirst().uniqueness(Uniqueness.RELATIONSHIP_GLOBAL) > .relationships(MyRelationships.SIMILAR) > .relationships(MyRelationships.CATEGORY) > .prune(TraversalFactory.pruneAfterDepth(2)).traverse(node) ) { > > > 2010/7/8 Mattias Persson <matt...@neotechnology.com> > > Your problem is that a node can't be visited more than once in a >> traversal, right? Have you looked at the new traversal framework in >> 1.1-SNAPSHOT? It solves that problem in that you can specify uniqueness for >> the traverser... you can instead say that each Relationship can't be visited >> more than once, but Nodes can. Your example: >> >> >> Map<Node, Integer> result = new HashMap<Node, Integer>(); >> for ( Node currentNode : TraversalFactory.createTraversalDescription() >> .breadthFirst().uniqueness(Uniqueness.RELATIONSHIP_GLOBAL) >> .relationships(MyRelationships.SIMILAR) >> .relationships(MyRelationships.CATEGORY) >> .prune(TraversalFactory.pruneAfterDepth(2)).traverse(node) ) { >> >> if(currentNode.hasProperty("category")) { >> >> if(result.get(currentNode) == null) { >> result.put(currentNode, 1); >> } else { >> result.put(currentNode, result.get(currentNode) + 1); >> } >> } >> } >> >> 2010/7/8 Rick Bullotta <rick.bullo...@burningskysoftware.com> >> >> A performance improvement might be achieved by minimizing object >>> creation/hash inserts using a "counter" wrapper. >>> >>> - Create a simple class "Counter" with a single public property "count" >>> of >>> type int (not Integer) with an initial value of 1 >>> >>> - Tweak your code to something like: >>> >>> public Map<String, Counter> findCategoriesForWord(String word) { >>> final Node node = index.getSingleNode("word", word); >>> final Map<String, Counter> result = new HashMap<String, >>> Counter>(); >>> if(node != null) { >>> Traverser traverserWords = >>> node.traverse(Traverser.Order.BREADTH_FIRST, >>> StopEvaluator.DEPTH_ONE, new ReturnableEvaluator() { >>> @Override >>> public boolean isReturnableNode(TraversalPosition >>> traversalPosition) { >>> final Node currentNode = >>> traversalPosition.currentNode(); >>> final Iterator<Relationship> >>> relationshipIterator = >>> currentNode.getRelationships(MyRelationships.CATEGORY).iterator(); >>> while(relationshipIterator.hasNext()) { >>> final Relationship relationship = >>> relationshipIterator.next(); >>> final String categoryName = (String) >>> relationship.getProperty("catId"); >>> >>> Counter counter = >>> result.get(categoryName); >>> >>> if(counter == null) { >>> result.put(categoryName, new Counter()); >>> } else { >>> ++counter.count; >>> } >>> } >>> return true; >>> } >>> }, MyRelationships.SIMILAR, Direction.BOTH); >>> traverserWords.getAllNodes(); >>> } >>> return result; >>> } >>> >>> >>> -----Original Message----- >>> From: user-boun...@lists.neo4j.org [mailto:user-boun...@lists.neo4j.org] >>> On >>> Behalf Of Java Programmer >>> Sent: Thursday, July 08, 2010 8:12 AM >>> To: Neo4j user discussions >>> Subject: Re: [Neo4j] Is it possible to count common nodes when >>> traversing? >>> >>> Hi, >>> Thanks for your answer but it's not exactly what I was on my mind - >>> word can belong to several categories, and different words can share >>> same category e.g.: >>> >>> "word 1" : "category 1", "category 2", "category 3" >>> "word 2" : "category 2", "category 3" >>> "word 3" : "category 3" >>> >>> there is relation between "word 1" and "word 2" and between "word 2" >>> and "word 3" (SIMILAR). >>> As a result when querying for "word 1" with depth 1, I would like to get: >>> "category 1" -> 1 (result), "category 2" -> 2, "category 3" -> 2 (not >>> 3 because it's out of depth) >>> >>> So far I have changed previous method to use the relationship with >>> property of categoryId, but I don't know if there won't be >>> a performance issues (I iterate for all relationship of the found node >>> (every similar), and store the categories in Map). If you could look >>> at it and tell me if the way of thinking is good, I would be very >>> appreciate: >>> >>> public Map<String, Integer> findCategoriesForWord(String word) { >>> final Node node = index.getSingleNode("word", word); >>> final Map<String, Integer> result = new HashMap<String, >>> Integer>(); >>> if(node != null) { >>> Traverser traverserWords = >>> node.traverse(Traverser.Order.BREADTH_FIRST, >>> StopEvaluator.DEPTH_ONE, new ReturnableEvaluator() { >>> @Override >>> public boolean isReturnableNode(TraversalPosition >>> traversalPosition) { >>> final Node currentNode = >>> traversalPosition.currentNode(); >>> final Iterator<Relationship> >>> relationshipIterator = >>> currentNode.getRelationships(MyRelationships.CATEGORY).iterator(); >>> while(relationshipIterator.hasNext()) { >>> final Relationship relationship = >>> relationshipIterator.next(); >>> final String categoryName = (String) >>> relationship.getProperty("catId"); >>> if(result.get(categoryName) == null) { >>> result.put(categoryName, 1); >>> } else { >>> result.put(categoryName, >>> result.get(categoryName) + 1); >>> } >>> } >>> return true; >>> } >>> }, MyRelationships.SIMILAR, Direction.BOTH); >>> traverserWords.getAllNodes(); >>> } >>> return result; >>> } >>> >>> >>> On Thu, Jul 8, 2010 at 1:23 PM, Craig Taverner <cr...@amanzi.com> wrote: >>> > Your description seems to indicate that each word only belongs to one >>> > category, and if you want the category count, you will always get 1. >>> But >>> > your code indicates tat: >>> > >>> > - You are counting the categories for similar works also >>> > - You are searching to depth 2 for both similar and category >>> > relationships, which seems to indicate you will also test all words >>> in >>> > categories found (which are ignored since you only test category >>> nodes, >>> but >>> > does cost time). >>> > >>> > If you do only have one category per word, and your question is "count >>> all >>> > categories for this word and similar words" I suggest remove the >>> category >>> > relationship from the traverser, change depth to depth 1, use >>> > ReturnableEvaluator.ALL and in a for loop over the traverser iteration, >>> just >>> > do: >>> > for(Node word: traverserWords){ >>> > Node category = >>> > word.getSingleRelationship(CATEGORY,OUTGOING).getEndNode(); >>> > ..add or increment hash.. >>> > } >>> > (perhaps you need to change the direction and call getStartNode() >>> depending >>> > on what you use for direction) >>> > >>> > Now you can also increase the depth for looking for less similar words, >>> > since the traverser only follows the SIMILAR type). Also, if you have >>> more >>> > than one category per word, don't use getSingleRelationship, but loop >>> over >>> > getRelationships(). If you move to a category tree (nested categories), >>> then >>> > create a new traverser inside the loop of the outer one. >>> > >>> > On Thu, Jul 8, 2010 at 12:47 PM, Java Programmer >>> <jprogrami...@gmail.com>wrote: >>> > >>> >> Hello, >>> >> >>> >> I have two nodes [Word] and [Category], each [Word] can have a >>> >> [Category], and different [Word] can share same [Category]. >>> >> [Word] to another [Word] has relationship SIMILAR, [Word] to >>> >> [Category] has relationship Category. >>> >> I need to count how many Words is in Category, up to given depth. >>> >> When I use my traverser code, it traverse well but skips the >>> >> Categories already found in earlier iterations. >>> >> Here is the sample which don't work as it should for my requirements >>> >> (category counter always is 1, logging tells me that category is >>> >> visited only once, even if it is connected to word in one node away >>> >> neighbourhood), any ideas what can be improved? >>> >> >>> >> public Map<Node, Integer> findCategoriesForWord(String word) { >>> >> final Node node = index.getSingleNode("word", word); >>> >> final Map<Node, Integer> result = new HashMap<Node, Integer>(); >>> >> if(node != null) { >>> >> Traverser traverserWords = >>> >> node.traverse(Traverser.Order.BREADTH_FIRST, >>> >> new StopEvaluator() { >>> >> @Override >>> >> public boolean isStopNode(TraversalPosition >>> >> traversalPosition) { >>> >> return traversalPosition.depth() == 2; >>> >> } >>> >> }, new ReturnableEvaluator() { >>> >> @Override >>> >> public boolean isReturnableNode(TraversalPosition >>> >> traversalPosition) { >>> >> Node currentNode = >>> traversalPosition.currentNode(); >>> >> boolean returnable = >>> >> traversalPosition.currentNode().hasProperty("category"); >>> >> if(returnable) { >>> >> if(result.get(currentNode) == null) { >>> >> result.put(currentNode, 1); >>> >> } else { >>> >> result.put(currentNode, >>> >> result.get(currentNode) + 1); >>> >> } >>> >> } >>> >> return returnable; >>> >> } >>> >> }, MyRelationships.SIMILAR, Direction.BOTH, >>> >> MyRelationships.CATEGORY, Direction.BOTH); >>> >> traverserWords.getAllNodes(); >>> >> } >>> >> return result; >>> >> } >>> >> >>> >> >>> >> -- >>> >> Best regards, >>> >> Adrian >>> >> >>> >> http://www.codeappeal.com/ >>> >> _______________________________________________ >>> >> Neo4j mailing list >>> >> User@lists.neo4j.org >>> >> https://lists.neo4j.org/mailman/listinfo/user >>> >> >>> > _______________________________________________ >>> > Neo4j mailing list >>> > User@lists.neo4j.org >>> > https://lists.neo4j.org/mailman/listinfo/user >>> > >>> >>> >>> >>> -- >>> Best regards, >>> Adrian >>> >>> http://www.codeappeal.com/ >>> _______________________________________________ >>> Neo4j mailing list >>> User@lists.neo4j.org >>> https://lists.neo4j.org/mailman/listinfo/user >>> >>> _______________________________________________ >>> Neo4j mailing list >>> User@lists.neo4j.org >>> https://lists.neo4j.org/mailman/listinfo/user >>> >> >> >> >> -- >> Mattias Persson, [matt...@neotechnology.com] >> Hacker, Neo Technology >> www.neotechnology.com >> > > > > -- > Mattias Persson, [matt...@neotechnology.com] > Hacker, Neo Technology > www.neotechnology.com > -- Mattias Persson, [matt...@neotechnology.com] Hacker, Neo Technology www.neotechnology.com _______________________________________________ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user