2016-03-25 1 views
0

enter image description hereSpring Data Neo4j Родитель Ребенок фильтрации

У меня отношения узла как выше диаграммы

моих классов

@NodeEntity 
public class User 
{ 


    @GraphId 
    private Long id; 

    @Property(name="name") 
    private String name; 


    @Relationship(type = "CAN_ACCESS", direction = Relationship.OUTGOING) 
    private List<Library> libraries; 


    // is this necessary ????? 
    @Relationship(type = "CAN_ACCESS", direction = Relationship.OUTGOING) 
    private List<Book> books; 


    public User() 
    { 

    } 

    // getters 
    // setters 
} 


@NodeEntity 
public class Library 
{ 
    @GraphId 
    private Long id; 

    @Property(name="name") 
    private String name; 


    @Relationship(type = "CONTAINS", direction = Relationship.OUTGOING) 
    private List<Book> books; 

    // is this necessary ????? 
    @Relationship(type = "CAN_ACCESS", direction = Relationship.INCOMING) 
    private List<User> users; 


    public Library() 
    { 

    } 

    // getters 
    // setters 
} 

@NodeEntity 
public class Book 
{ 
    @GraphId 
    private Long id; 

    @Property(name="name") 
    private String name; 

    // is this necessary ????? 
    @Relationship(type = "CONTAINS", direction = Relationship.INCOMING) 
    private Library library; 

    // is this necessary ????? 
    @Relationship(type = "CAN_ACCESS", direction = Relationship.INCOMING) 
    private List<User> users; 


    public Book() 
    { 

    } 

    // getters 
    // setters 
} 

У меня есть узел User Id = 21 и библиотека узел Id = 32 . Я хочу запросить Книги, принадлежащие Библиотеке 32, но доступен только пользователю 21.

Примечание - хотя пользователь 21 «CAN_ACCESS» Библиотека 32, это не означает, что он «CAN_ACCESS» все книги «СОДЕРЖИТ» в библиотеке 32

Мой текущий подход в моем классе обслуживания является

@Autowired 
private LibraryRepository libraryRepository; 

@Autowired 
private UserRepository userRepository; 

@Autowired 
private BookRepository bookRepository; 

@Autowired 
private Session session; 


public void testGraph() 
{ 
    Long userId = 21; 
    Long libId = 32; 
    int depth = 1; 

    Library library = libraryRepository.findOne(32,depth); 
    List<Book> books = library.getBooks(); 
    List<Book> userAccessibleBooks = getUserAccessibleBooks(books,userId); 
} 

public List<Book> getUserAccessibleBooks(List<Book> books,Long userId) 
{ 
    // Loop over book list and get List<User> users; 
    // check this user "CAN_ACCESS" the book 
    // return accessible book list 
} 

Я не думаю, что это лучший подход. Предполагая, что у вас есть миллионы книг в библиотеке

Любое решение? или мне что-то не хватает в данных весны neo4j (Filters)?

Резюме

Я хочу, чтобы получить библиотеку 32 фильтрованного списка книг, как дети, которые пользователем 21 «CAN_ACCESS»

+0

Ваш подход кажется хорошим, потому что если они имеют доступ к библиотеке не предоставляет доступа для каждой книги в ней вы должны указать для каждой книги, если у вас есть доступ или нет. Я рекомендую переименовать каждое отношение 'CAN_ACCESS', например' CAN_ACCESS_BOOK' и 'CAN_ACCESS_LIBRARY' – Supamiu

ответ

1

Вы хотите использовать искатель хранилища для этого вида запросов. Вы хотите вернуть List<Book>, чтобы он перешел в BookRepository.

Самый простой способ определить Cypher запрос:

MATCH (u:User), (l:Library) 
WHERE 
ID(u) = {userId} AND ID(u) = {libraryId} 
MATCH 
(u)-[:CAN_ACCESS]->(b:Book), 
(l)-[:CONTAINS]-(b) 
RETURN b 

Использование собственных идентификаторов графа не очень рекомендуется, так что если вы приведете например, UUID запрос может выглядеть следующим образом:

MATCH 
(u:User {uuid:{userUuid}}), 
(l:Library {uuid:{libraryUuid}}), 
(u)-[:CAN_ACCESS]->(b:Book), 
(l)-[:CONTAINS]-(b) 
RETURN b 

Затем добавьте метод поиска с этим запросом в BookRepository интерфейс:

@Query("MATCH 
(u:User {uuid:{userUuid}}), 
(l:Library {uuid:{libraryUuid}}), 
(u)-[:CAN_ACCESS]->(b:Book), 
(l)-[:CONTAINS]-(b) 
RETURN b") 
List<Book> findBooksByUserAndLibrary(@Param("userUuid") String userUuid, @Param("libraryUuid) String libraryUuid);