[Neo4j] Is it possible to count common nodes when traversing?

2010-07-08 Thread Java Programmer
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 MapNode, Integer findCategoriesForWord(String word) {
final Node node = index.getSingleNode(word, word);
final MapNode, Integer result = new HashMapNode, 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


Re: [Neo4j] Is it possible to count common nodes when traversing?

2010-07-08 Thread Java Programmer
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 MapString, Integer findCategoriesForWord(String word) {
final Node node = index.getSingleNode(word, word);
final MapString, Integer result = new HashMapString, 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 IteratorRelationship
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.comwrote:

 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 MapNode, Integer findCategoriesForWord(String word) {
        final Node node = index.getSingleNode(word, word);
        final MapNode, Integer result = new HashMapNode, Integer();
        if(node != null) {
            Traverser traverserWords =
 node.traverse(Traverser.Order.BREADTH_FIRST,
                new StopEvaluator() {
                   �...@override
                    public boolean isStopNode(TraversalPosition
 traversalPosition