-->

Monday, 16 January 2012

Finding Anagrams With Neo4j (Pattern Matching)

In my previous post on this subject I showed how I found anagrams by implementing ReturnableEvaluator. After I finished writing that program, I found this article that included a section on pattern matching. I wrote a method to see how this would work.

Note: the problem I am trying to solve is from horse racing. I cannot currently solve that problem because I do not have the information in a database. This is an analogous problem where the could easily be placed in the database.







/**
  * 10. Start at the node representing the length of the word
  * 20. Create a relationship from theLengthNode to a wordNode
  * 30. Iterate the characters in the multiset
  * 32. Create a pattern node representing current character and
  *     add a property constraint that it must match the current character
  * 34. Add a relationship between the character pattern node and word node
  * 40. Get the matcher
  * 50. Get the iterator and iterate
  */
 public void findAnagramUsingPatternMatching(){
  
  // 10. length node should represent 4 and can be only one node
  //    so we associate it with that node
  final PatternNode theLengthNode = new PatternNode();
  theLengthNode.setAssociation(lengthNode);
  
  // 20. wordNode could be any node with the correct properties
  final PatternNode wordNode = new PatternNode();
  theLengthNode.createRelationshipTo(wordNode, RelTypes.HAS_LENGTH);

  
  // 30. Iterate the characters in the multiset
  for (final Character c : multiset){
   
   // 32. Create a pattern node representing current character and
   //     add a property constraint that it must match the current character
   PatternNode characterPatternNode = new PatternNode();
   characterPatternNode.addPropertyConstraint( "letter",
     CommonValueMatchers.exact( c ) );
   
   // 34. Add a relationship between the character pattern node and word node
   PatternRelationship localPatternRelationship = wordNode.createRelationshipTo(characterPatternNode, RelTypes.HAS_LETTER);
   localPatternRelationship.addPropertyConstraint("occurrences", new ValueMatcher(){
    public boolean matches(Object value){
     boolean result = (int)value == multiset.count(c);
     return result;
    }
   });
  }


  // 40. Get the matcher
  PatternMatcher pm = PatternMatcher.getMatcher();
  
  // 50. Get the iterator and iterate
  final Iterable matches = pm.match(theLengthNode, lengthNode);
  Iterator iter = matches.iterator();
  while(iter.hasNext()){
   PatternMatch match = iter.next();
   Node matchNode = match.getNodeFor(wordNode);
   System.out.println("matches from PM: " + matchNode.getProperty("word") );
  }
 }

Arrow Key Nav