如何使用Spring Data Neo4j在查询中指定深度?(How to specify depth in queries with Spring Data Neo4j?)

编程入门 行业动态 更新时间:2024-10-27 09:45:08
如何使用Spring Data Neo4j在查询中指定深度?(How to specify depth in queries with Spring Data Neo4j?)

我尝试使用Neo4j和Spring Data(spring-data-neo4j 4.2.0.RELEASE)进行目录结构。

我有一个目录bean:

@NodeEntity public class Directory { @GraphId private Long id; private String name; @Relationship(type = "HAS_CHILD_CONTENT", direction = Relationship.OUTGOING) public Set<Directory> subDirectories; public void hasChildContent(Directory subDir) { if (subDirectories == null) { subDirectories = new HashSet<>(); } subDirectories.add(subDir); }

和我的存储库:

public interface DirectoryRepository extends GraphRepository<Directory> { @Query("MATCH (a:Directory) WHERE NOT ()-[:HAS_CHILD_CONTENT]->(a) RETURN a ORDER BY a.name ASC") List<Directory> findAllRoots(); Directory findOneByName(String name, @Depth int depth); }

我的问题是目录有一个他的子目录列表,我不想在获取根目录时获取数据库中的所有目录。

目前,如果我创建此数据样本:

Directory root = new Directory("root"); Directory rootLevel1 = new Directory("rootLevel1"); Directory rootLevel2 = new Directory("rootLevel2"); root.hasChildContent(rootLevel1); rootLevel1.hasChildContent(rootLevel2); directoryRepository.save(root);

并选择根节点:

directoryRepository.findAllRoots();

我得到根目录,将rootLevel1作为subDir,其root3作为subDir。

我想获取root,其中rootLevel1具有null(作为subDir)。 所以我不会获取数据库的整个目录。

我尝试了@Depth param,但电话:

directoryRepository.findOneByName("root", 0);

获取根目录,将rootLevel1作为subDir,将rootLevel2作为subDir。 好像没有考虑到深度。

我怎样才能选择只有他的子目录的节点,而不是子目录的子目录的子目录的子目录?

谢谢。

[编辑]

我发现在集成测试中删除Transactional注释会影响SDN的fecthing系统。

通过Transactional注释,SDN急切地获取所有子目录并从Neo4J加载整个目录结构。

没有Transactional注释,SDN懒惰地获取,我的Directory bean作为“subDirectories”属性为null。

这解决了我的问题,但没有回答背后的问题:如何设置自定义深度以获取。

I try to do a directory structure with Neo4j and Spring Data (spring-data-neo4j 4.2.0.RELEASE).

I have a Directory bean :

@NodeEntity public class Directory { @GraphId private Long id; private String name; @Relationship(type = "HAS_CHILD_CONTENT", direction = Relationship.OUTGOING) public Set<Directory> subDirectories; public void hasChildContent(Directory subDir) { if (subDirectories == null) { subDirectories = new HashSet<>(); } subDirectories.add(subDir); }

and my Repository :

public interface DirectoryRepository extends GraphRepository<Directory> { @Query("MATCH (a:Directory) WHERE NOT ()-[:HAS_CHILD_CONTENT]->(a) RETURN a ORDER BY a.name ASC") List<Directory> findAllRoots(); Directory findOneByName(String name, @Depth int depth); }

My problem is that a directory has a list of his sub directories, and I don't want to fetch all the directories in the database when I fetch a root directory.

At the moment, if I create this data sample :

Directory root = new Directory("root"); Directory rootLevel1 = new Directory("rootLevel1"); Directory rootLevel2 = new Directory("rootLevel2"); root.hasChildContent(rootLevel1); rootLevel1.hasChildContent(rootLevel2); directoryRepository.save(root);

And select the root nodes :

directoryRepository.findAllRoots();

I get the root dir, having the rootLevel1 as subDir whom has the rootLevel2 as subDir.

I want to fetch just root having rootLevel1 having null (as subDir). So I don't fetch the whole directories of the DB.

I tried the @Depth param, but the call :

directoryRepository.findOneByName("root", 0);

fetches the root dir, having the rootLevel1 as subDir whom has the rootLevel2 as subDir. As if the depth was not taken into account.

How could I select a node with just his subDirectories, but not the subDirectories of subDirectories of subDirectories of ... ?

Thanks.

[EDIT]

I found that removing the Transactional annotation on my integration test affects the fecthing system of SDN.

With Transactional annotation, SDN fetches eagerly all subDirectories and loads the whole directory structure from Neo4J.

Without Transactional annotation, SDN fetched lazyly and my Directory bean has null as "subDirectories" attribute.

This solves my problem, but doesn't answer the question behind : How to set the custom depth to fetch.

最满意答案

这可能是因为您共享相同的基础会话以供您编写和阅读。

当您读取实体时,SDN / OGM检测到它们已经在会话中(基于id)。 它会在会话中返回它们,完全填充。

当您删除@Transactional ,每个数据库访问都在新的新会话中执行,给出预期的结果。

如果您在写入后需要以任何理由阅读,您可能需要注入一个OGM会话来调用session.clear()来强制进行会话刷新。

This is probably because you share the same underlying session for you write and your read.

When you read the entities, SDN/OGM detects they are already in the session (based on the id). It returns them as they are in the session, fully populated.

When you remove the @Transactional, each db access executes in a new fresh session, giving the expected result.

If you need for any reason to read just after write, you might want to inject an OGM session to call a session.clear() to force a session refresh.

更多推荐

本文发布于:2023-07-20 02:53:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1192056.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   深度   Spring   Neo4j   Data

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!