需要帮助将 Neo4j Cypher 请求转换为 JPQL

Need help converting Neo4j Cypher request to JPQL

我有需要转换为 JPQL 的 Neo4j Cypher 请求:

MATCH (p:Person)-[:worksForOrganisation]->
    (:Organisation)-[*0..2]->(:Organisation)
    -[:possessesResource|:accessesResource|:supportsResource]->(:Software)
    <-[:categoryContains]-(c:ResourceCategory)
WHERE id(p)=({personId})
RETURN c

此请求从具有标识符 personId 的唯一 Person 开始。

我们知道这个人为一个(在极少数情况下,很多)Organisation工作。

我们知道每个组织都可以拥有、访问或支持类型为 Software 的资源。

我们希望 return ResourceCategories "contain" Software 人可以使用,鉴于不同组织之间可能存在关联,授予 him/her 使用另一个组织的软件的权利。

将其转换为 JPQL 的困难来自:

  1. (:组织)-[*0..2]->(:组织)
  2. (:组织)-[:possessesResource|:accessesResource|:supportsResource]->(:Software)

点1(:Organisation)-[*0..2]->(:Organisation)表示最多三个"Organisation"节点之间的可选关系。这个想法是,找到一个 "Organisation" 节点后,我们还对从至多两个其他 "Organisations" 开始的所有路径感兴趣,这些路径与该人所工作的组织相关联。

点2 : (:Organisation)-[:possessesResource|:accessesResource|:supportsResource]->(:Software)表示,找到一个"Organisation",可以关联到一个"Software",有3种关系(或者甚至是各种不同的关系)。

到目前为止我的想法(真的不完整,我知道):

@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);

问题:

谢谢!

UPDATE :如 JPQL doesn't support UNION,那么我该如何重现 "variable length join"?

经过大量 的工作,我们相信我们找到了相应的 JPQL 请求。

如果有人想知道如何模拟 Cypher 请求的困难部分,即可变长度的路径 (Organisation)-[*0..2]->(Organisation),我相信我们在 JPQL 中根本无法做到,我们必须对待所有超级 class "Organisation" 的可能实例是 "Community"、"Institution"、"TeachingDepartment" 和 "AdministrativeDepartment".

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 简单得多。希望它会成为一个标准,所以我不得不切换到关系数据库的原因有一天会消失。