Announcement Announcement Module
Collapse
No announcement yet.
Help with reverse relationship query Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help with reverse relationship query

    I have a repository interface extending GraphRepository. I use this for almost all of my graph access, and that works well. Now I'd like to do something, and I'm not sure the best way to accomplish it.

    I have thow classes, A & B. A has a set of B; this is a one way (in my Java code) relationship. I know that even one way relationships can be reversed, and I can see this clearly in the neo4j-sh app. An instance of B looks like this:
    (me)<-[:OWNER_OF]-(Test1,2)
    (me)<-[:OWNER_OF]-(Test2,5)
    (me)<-[:OWNER_OF]-(Test1,4)

    So it (correctly) shows three in-bound connections.

    What I want to do is have a method that returns the count of inbound connections. This way, when I delete an instance of B, I only remove it from the correct container, and only delete it from the graph db when there are no more incomming connections. Mu understanding is I can annotate a methid in my repository interfacew with queries. That is what I'd like to do (unless there is a better way I'm over-looking).

    Any help appreciated.

  • #2
    treaves,

    Cypher-query-annotated methods are quite good for this:

    Code:
    @NodeEntity
    class Foo {
        @GraphId
        Long id;
    
        Bar bar;
    
        Foo() {
        }
    
        Foo(Bar bar) {
            this.bar = bar;
        }
    }
    
    @NodeEntity
    class Bar {
        @GraphId
        Long id;
    }
    
    interface FooRepository extends CRUDRepository<Foo> {
        @Query("start n=node(*) return count(n)")
        int countNodes();
    
        @Query("start n=node:__types__(className=\"cypher.mutation.Bar\") match n<-[r?:bar]-m where r is null return count(n)")
        int countUnconnectedBars();
    
        @Query("start n=node:__types__(className=\"cypher.mutation.Bar\") match n<-[r?:bar]-m where r is null delete n")
        void deleteUnconnectedBars();
    }
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration
    public class MutatingCypherQueriesTests {
        @Configuration
        @EnableNeo4jRepositories
        static class TestConfig extends Neo4jConfiguration {
    
            @Bean
            GraphDatabaseService graphDatabaseService() {
                return new ImpermanentGraphDatabase();
            }
    
        }
    
        @Autowired
        private GraphDatabaseService graphDatabaseService;
    
        @Autowired
        private FooRepository fooRepository;
    
        @Autowired
        private Neo4jTemplate template;
    
        @Before
        public void before() {
            Neo4jHelper.cleanDb(graphDatabaseService, true);
    
            Transaction transaction = graphDatabaseService.beginTx();
            Bar bar1 = template.save(new Bar());
            Bar bar2 = template.save(new Bar());
            Bar bar3 = template.save(new Bar());
            template.save(new Foo(bar1));
            template.save(new Foo(bar1));
            template.save(new Foo(bar2));
            transaction.success();
            transaction.finish();
        }
    
        @Test
        public void shouldDeleteUnconnectedNodes() throws Exception {
            assertThat(fooRepository.countNodes(), is(6));
            assertThat(fooRepository.countUnconnectedBars(), is(1));
    
            Transaction transaction = graphDatabaseService.beginTx();
            fooRepository.deleteUnconnectedBars();
            transaction.success();
            transaction.finish();
    
            assertThat(fooRepository.countNodes(), is(5));
            assertThat(fooRepository.countUnconnectedBars(), is(0));
        }
    }
    Regards,

    Lasse

    Comment

    Working...
    X