Results 1 to 10 of 18

Thread: Getting Neo4j cypher queries to work in java GraphRepository

Hybrid View

  1. #1
    Join Date
    Aug 2012
    Location
    New York, NY
    Posts
    9

    Default Getting Neo4j cypher queries to work in java GraphRepository

    I'm using a Neo4j database with various node classes and would like to search through the parameter strings of one particular node class. For example, if I have three nodes in class.MyNode, one with String name = "foo", another with name = "bar" and a third with name = "car", if I search for "ar", I would like to return a list containing nodes "bar" and "car".

    The following cypher query works perfectly well in Neo4j's data browser :

    Code:
    START n=node:__types__(className='com.myapp.MyNode')
    WHERE n.name=~ /(?i).*xyz.*/
    RETURN n
    However, when I add it to my repository, it returns all the nodes of class.MyNode and not the subset I need. Here is the code I've been using for the repository:

    Code:
    public interface MyNodeRepository extends GraphRepository<MyNode>,
    	RelationshipOperationsRepository<MyNode>,
    	NamedIndexRepository<MyNode>{
    	
    	@Query(	"START n=node:__types__(className='com.myapp.MyNode')"+ 
    			"WHERE n.name=~ /(?i).*{0}.*/"+
    			"RETURN n")
            Set<MyNode> getNodes(String search);	
    }
    And here is the node:

    Code:
    @NodeEntity
    public class MyNode {
    	@Indexed(indexType=IndexType.FULLTEXT, indexName="name") 
    	@Fetch private String name;
    
            etc
    }

    I'm passing parameters just like the bible suggests and I've been pulling my hair out trying to figure out why this doesn't work.

    Any thoughts on how to fix this would be much appreciated!!!

  2. #2
    Join Date
    May 2012
    Posts
    107

    Default

    Michael,

    I'd suggest taking advantage of SDN's auto-repo-foo: http://static.springsource.org/sprin.../html/#d5e1308

    Code:
    @NodeEntity
    class MyNode {
        @GraphId
        private Long id;
    
        @Indexed(indexType = IndexType.FULLTEXT, indexName = "name")
        private String name;
    
        MyNode() {
        }
    
        public MyNode(String name) {
            this.name = name;
        }
    }
    
    interface MyNodeRepository extends GraphRepository<MyNode> {
        Page<MyNode> findByNameLike(String name, Pageable page);
    }
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration
    public class FullTextSearchTests {
        @Autowired
        private MyNodeRepository myNodeRepository;
    
        @Configuration
        @EnableNeo4jRepositories
        static class Config extends Neo4jConfiguration {
            @Bean
            public GraphDatabaseService graphDatabaseService() {
                return new ImpermanentGraphDatabase();
            }
        }
    
        @Test
        public void shouldFindBySubstring() throws Exception {
            myNodeRepository.save(new MyNode("foo"));
            myNodeRepository.save(new MyNode("bar"));
            myNodeRepository.save(new MyNode("car"));
    
            assertThat(myNodeRepository.findByNameLike("*ar*", new PageRequest(0, 20)).getNumberOfElements(), is(2));
            assertThat(myNodeRepository.findByNameLike("*o", new PageRequest(0, 20)).getNumberOfElements(), is(1));
            assertThat(myNodeRepository.findByNameLike("ca?", new PageRequest(0, 20)).getNumberOfElements(), is(1));
        }
    }

  3. #3
    Join Date
    Aug 2012
    Location
    New York, NY
    Posts
    9

    Default

    Thank you for the prompt reply! That is working for me now.

  4. #4
    Join Date
    Aug 2012
    Location
    New York, NY
    Posts
    9

    Default

    Sorry but I have to get back to this problem. Although the auto-repo is good for simple queries, I still need to use the regular expression for more complicated queries.

    For example:

    Code:
    public interface MyRepository extends GraphRepository<User>,
    	RelationshipOperationsRepository<User>,
    	NamedIndexRepository<User>{
    	
    	@Query(	"START user=node({0}) "+
    	"MATCH user-[:FRIENDS*1..2]-friends "+
    	"WITH user, friends "+
    	"MATCH friends-[:REL*1]->relatives "+
    	"WHERE relatives.name=~ /(?i).*{1}.*/ "+
    	"RETURN relatives")	
    	Set<User> findRelativesOfFriends(long userId, String search);
    }
    This works in the data browser, it returns a subset of relatives, but in java regardless of what search parameter I pass, it always returns the whole set.

    Am I doing something wrong?

  5. #5
    Join Date
    May 2012
    Posts
    107

    Default

    Quote Originally Posted by MichaelJaniak View Post
    Code:
    public interface MyRepository extends GraphRepository<User>,
    	RelationshipOperationsRepository<User>,
    	NamedIndexRepository<User>{
    	
    	@Query(	"START user=node({0}) "+
    	"MATCH user-[:FRIENDS*1..2]-friends "+
    	"WITH user, friends "+
    	"MATCH friends-[:REL*1]->relatives "+
    	"WHERE relatives.name=~ /(?i).*{1}.*/ "+
    	"RETURN relatives")	
    	Set<User> findRelativesOfFriends(long userId, String search);
    }
    This works in the data browser, it returns a subset of relatives, but in java regardless of what search parameter I pass, it always returns the whole set.
    Well, it actually does what you ask it; so it interprets that regex as
    Code:
    match .* one time, then match .* a bunch of times
    - the {1} is not substituted, it is taken literally

    Instead, do
    Code:
    @Query(	"START user=node({0}) "+
    	"MATCH user-[:FRIENDS*1..2]-friends "+
    	"WITH user, friends "+
    	"MATCH friends-[:REL*1]->relatives "+
    	"WHERE relatives.name=~ {1} "+
    	"RETURN relatives")	
    	Set<User> findRelativesOfFriends(long userId, String regex);
    
    ...
    
    myRepo.findRelativesOfFriends(42, "(?i).*my search string.*");
    Let me know if it works.

    Regards,

    Lasse

  6. #6
    Join Date
    Aug 2012
    Location
    New York, NY
    Posts
    9

    Default

    That's perfect, works exactly like that, thank you for your help!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •