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