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
_______________________________________________
Neo4j mailing list
User@lists.neo4j.org
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to