微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SpringData Neo4j @Query 不填充 @Relationship 节点

如何解决SpringData Neo4j @Query 不填充 @Relationship 节点

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 使用方法名称/签名生成查询完美运行,并返回完全填充的 Asset 和 Organization 节点。

但是,当使用@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标记的repository方法来加入@Relationship注解定义的父/子节点?

解决方法

使用@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?)您可以删除自定义查询并使用 findByTrackerId 的开箱即用 SPEL 和存储库方法将创建一个自动的 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_BYASSIGNED_TO 都是来自 :Tracker 的传出关系?

收集是因为这个:

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

,

@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 子句与我的实际关系名称相匹配,因为这样在查看原始结果时会显得更简洁一些。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。