我有Neo4j Cypher请求我需要转换为JPQL:
MATCH (p:Person)-[:worksForOrganisation]->
(:Organisation)-[*0..2]->(:Organisation)
-[:possessesResource|:accessesResource|:supportsResource]->(:Software)
<-[:categoryContains]-(c:ResourceCategory)
WHERE id(p)=({personId})
RETURN c
此请求从标识为Person
的唯一personId
开始。
我们知道这个人适用于一个人(在极少数情况下很多人)Organisation
s。
我们知道每个组织都可以拥有,访问或支持Software
类型的资源。
我们想要返回ResourceCategories
“包含”此人可以使用的Software
,因为不同组织之间可能存在关联,这使得他/她有权使用其他组织的软件。
将其转换为JPQL的困难来自:
第1点:(:Organisation)-[*0..2]->(:Organisation)
表示最多三个“组织”节点之间的可选关系。我们的想法是,在找到“组织”节点之后,我们也对所有路径感兴趣,这些路径最多来自与该人员所在组织相关联的其他两个“组织”。
第2点:(:Organisation)-[:possessesResource|:accessesResource|:supportsResource]->(:Software)
意味着,在找到“组织”后,它可能与具有三种关系的“软件”相关(甚至可能与各种各样)。
到目前为止我的想法(真的不完整,我知道):
@Query("SELECT rc FROM Person p, Organisation o1, Organisation o2, Organisation o3, Software s, ResourceCategory rc " +
"WHERE p.id = :personId " +
"AND o1 MEMBER OF p.worksForOrganisations " +
"AND s MEMBER OF rc.resources")
Set<ResourceCategoryEntity> getCategoriesForPerson(@Param("personId") Long personId);
问题:
谢谢!
更新:如JPQL doesn't support UNION,那我该如何重现“变长连接”?
答案 0 :(得分:1)
在很多工作之后,我们相信我们找到了相应的JPQL请求。
如果有人想知道如何模仿Cypher请求的困难部分,这是可变长度(Organisation)-[*0..2]->(Organisation)
的路径,我相信我们根本不能在JPQL中这样做,我们必须处理所有可能的实例超级“组织”,即“社区”,“机构”,“教学部门”和“行政部门”。
SELECT DISTINCT (rc) FROM ResourceCategory rc JOIN rc.resources d
WHERE d.id IN ( SELECT e.id FROM Documentation e, Organisation o, Person u
WHERE u.id = :personId
AND o MEMBER OF u.worksForOrganisations
AND ( o = e.organisationPossessingResource
OR o = e.organisationSupportingResource
OR o MEMBER of e.organisationsHavingAccessToResource
)
)
OR d.id IN ( SELECT d.id FROM Documentation d, Organisation o
WHERE TYPE(o) IN (Institution)
AND ( o = d.organisationPossessingResource
OR o = d.organisationSupportingResource
OR o MEMBER of d.organisationsHavingAccessToResource
)
AND o.id IN (
SELECT i.id FROM Institution i, AdministrativeDepartment ad, Person u
WHERE u.id = :personId
AND ad MEMBER OF u.worksForOrganisations
AND ad MEMBER OF i.administrativeDepartments
)
)
OR d.id IN ( SELECT d.id FROM Documentation d, Organisation o
WHERE TYPE(o) IN (Institution)
AND ( o = d.organisationPossessingResource
OR o = d.organisationSupportingResource
OR o MEMBER of d.organisationsHavingAccessToResource
)
AND o.id IN (
SELECT i.id FROM Institution i, TeachingDepartment td, Person u
WHERE u.id = :personId
AND td MEMBER OF u.worksForOrganisations
AND td MEMBER OF i.teachingDepartments
)
)
OR d.id IN ( SELECT d.id FROM Documentation d, Organisation o
WHERE TYPE(o) IN (Community)
AND ( o = d.organisationPossessingResource
OR o = d.organisationSupportingResource
OR o MEMBER of d.organisationsHavingAccessToResource
)
AND o.id IN (
SELECT c.id FROM Community c, Institution i, AdministrativeDepartment ad, Person u
WHERE u.id = :personId
AND ad MEMBER OF u.worksForOrganisations
AND ad MEMBER OF i.administrativeDepartments
AND c MEMBER OF i.communities
)
)
OR d.id IN ( SELECT d.id FROM Documentation d, Organisation o
WHERE TYPE(o) IN (Community)
AND ( o = d.organisationPossessingResource
OR o = d.organisationSupportingResource
OR o MEMBER of d.organisationsHavingAccessToResource
)
AND o.id IN (
SELECT c.id FROM Community c, Institution i, TeachingDepartment td, Person u
WHERE u.id = :personId
AND td MEMBER OF u.worksForOrganisations
AND td MEMBER OF i.teachingDepartments
AND c MEMBER OF i.communities
)
)
OR d.id IN ( SELECT d.id FROM Documentation d, Organisation o
WHERE TYPE(o) IN (Community)
AND ( o = d.organisationPossessingResource
OR o = d.organisationSupportingResource
OR o MEMBER of d.organisationsHavingAccessToResource
)
AND o.id IN (
SELECT c.id FROM Community c, Institution i, Person u
WHERE u.id = :personId
AND i MEMBER OF u.worksForOrganisations
AND i MEMBER OF c.institutions
)
)
脚注:这表明Cypher绝对摇滚,比同等的JPQL简单得多。希望它会成为一个标准,所以我不得不切换到关系数据库的原因有一天会消失。