【问题标题】:SpringData Neo4j @Query does not populate @Relationship NodesSpring Data Neo4j @Query 不填充 @Relationship 节点
【发布时间】:2021-06-20 04:05:20
【问题描述】:

neo4j @Query 注解的 Spring Data 不会填充由 @Relationship 注解标记的任何子/父节点。

在 SpringData Repository 类中使​​用标准的 @CrudRepository 或 @PagingAndSortingRepository 查询时,子/父节点类将返回完整填充。

存储库接口

@Repository("trackerRepository")
public interface TrackerRepository extends PagingAndSortingRepository<Tracker, String> {

    Tracker findByTrackerId(@NotNull String trackerId);
}

节点类

public final class Tracker extends Node {

    @NotNull
    @JsonProperty("trackerId")
    private String trackerId;

    @NotNull
    @Relationship(type = "ASSIGNED_TO")
    @JsonProperty("asset")
    private Asset asset;

    @NotNull
    @Relationship(type = "ISSUED_BY")
    @JsonProperty("organization")
    private Organization organization;
}

使用 findByTrackerId 方法时,Spring 使用方法名称/签名生成的查询完美运行,并返回完全填充的资产和组织节点。

但是,当使用@Query 注解而不是从方法签名生成的 Spring 查询时,@Relationship 节点不会与查询响应一起返回。

存储库接口

@Repository("trackerRepository")
public interface TrackerRepository extends PagingAndSortingRepository<Tracker, String> {

    @Query("MATCH (tracker:Tracker) WHERE (tracker.trackerId = $trackerId) RETURN tracker")
    Tracker findByTrackerId(@NotNull @Param("trackerId") String trackerId);
}

是否可以配置带有@Query 标记的存储库方法来加入@Relationship 注解定义的父/子节点?

【问题讨论】:

    标签: java spring neo4j spring-data-neo4j


    【解决方案1】:

    使用@Query 编写自定义查询时,您需要准确指定要返回的内容:

    @Relationship(type = "ASSIGNED_TO")
    @JsonProperty("asset")
    private Asset asset;
    
    @NotNull
    @Relationship(type = "ISSUED_BY")
    @JsonProperty("organization")
    private Organization organization;
    
    

    或者(我假设这是带有 Spring Data 的 SDN 6,而不是 SDN 5 和 OGM?)您可以删除自定义查询并使用开箱即用的 SPEL findByTrackerId 和存储库方法将创建一个自动的 Cypher 查询,该查询由 @Repository 方法无缝序列化。

    通常,当需要编写比 SDN 糖提供的更高效的查询时,自定义 @Query 很有用。

    但是要更直接地回答您的问题,这应该可行:

    @Query("MATCH (tracker:Tracker {trackerId: $trackerId})
    WITH tracker
    OPTIONAL MATCH (tracker)-[r_issued_by:ISSUED_BY]->(organization:Organization)
    WITH tracker, COLLECT(r_issued_by) AS organization_rels, COLLECT(DISTINCT organization) AS organizations 
    OPTIONAL MATCH (tracker)-[r_assigned_to:ASSIGNED_TO]->(asset:Asset)
    RETURN tracker, organization_rels, organizations, COLLECT(r_assigned_to) AS asset_rels, COLLECT(DISTINCT asset) AS assets;")
    

    查看您的注释,ISSUED_BY 和 ASSIGNED_TO 似乎都是来自 :Tracker 的传出关系?

    收集是因为:

    https://community.neo4j.com/t/sdn-rx-dynamic-relationships-not-being-populated-with-custom-query/24456

    【讨论】:

    • 是的,ISSUED_BY 和 ASSIGNED_TO 关系是传出的,您提供的查询有效!我们的目的不是避免强大的 SDN 糖,而是能够避免更复杂的基于关系的过滤器的不稳定方法名称: ] 组织 ID); `` 然而,SDN 糖的价值大大超过了方法名称语法的感知价值。有比带下划线的方法名更糟糕的事情。 :-) 绿色复选标记和 MASSIVE 协助 +1!
    【解决方案2】:

    @false_memories 是正确的,但在这种情况下,WITH 子句不是必需的。如果您只是使用 match 子句中的变量,则不需要 WITH。仅当您以某种方式操作变量时才需要WITH:

    https://neo4j.com/docs/cypher-manual/current/clauses/with/#with-filter-on-aggregate-function-results

    此外,您的 @NotNull 注释中似乎需要您的关系,因此您应该删除 OPTIONAL

    所以一个稍微好一点的查询是:

    @Query("MATCH (tracker:Tracker {trackerId: $trackerId})
    MATCH (tracker)-[r_issued_by:ISSUED_BY]->(organization:Organization)
    MATCH (tracker)-[r_assigned_to:ASSIGNED_TO]->(asset:Asset)
    RETURN tracker,
      COLLECT(r_issued_by), COLLECT(organization) AS organization,
      COLLECT(r_assigned_to), COLLECT(asset) AS asset")
    

    我喜欢将as 子句与我的实际关系名称相匹配,因为它在查看原始结果时看起来更清晰。

    【讨论】:

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