【问题标题】:Spring Data Neo4j Parent Child filteringSpring Data Neo4j 父子过滤
【发布时间】:2016-04-20 17:39:19
【问题描述】:

我的节点关系如上图

我的课程

@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  
}

我有用户节点 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
}

我认为这不是最好的方法。假设您在图书馆中有数百万本书

有什么解决办法吗?还是我在 Spring data neo4j (Filters) 中遗漏了什么?

总结

我想将图书馆 32 过滤后的图书列表作为用户 21“CAN_ACCESS”的孩子

【问题讨论】:

  • 您的方法似乎不错,因为如果有权访问图书馆并不能授予对其中每一本书的访问权限,那么您必须为每本书指定是否有权访问。我建议重命名每个CAN_ACCESS 关系,例如CAN_ACCESS_BOOKCAN_ACCESS_LIBRARY

标签: java spring neo4j spring-data-neo4j spring-data-neo4j-4


【解决方案1】:

您想对此类查询使用存储库查找器。你想返回List&lt;Book&gt;,所以这将进入 BookRepository。

最简单的方法是定义一个密码查询:

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

真的不推荐使用原生图形 ID,所以如果你引入例如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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多