Spring Data Neo4j @Query 不填充@Relationship 节点
SpringData Neo4j @Query does not populate @Relationship Nodes
neo4j @Query 注释的 Spring 数据不会填充任何由 @Relationship 注释标记的 child/parent 节点。
当在 Spring 数据存储库 class 中使用标准的 @CrudRepository 或 @PagingAndSortingRepository 查询时,Child/Parent 节点 class 将返回完整填充。
存储库接口
@Repository("trackerRepository")
public interface TrackerRepository extends PagingAndSortingRepository<Tracker, String> {
Tracker findByTrackerId(@NotNull String trackerId);
}
节点Class
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 使用方法 name/signature 生成的查询完美运行,returns 完全填充资产和组织节点。
但是,当使用 @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 注释定义的parent/child 节点?
使用@Query 编写自定义查询时,您需要准确指定要返回的内容:
@Relationship(type = "ASSIGNED_TO")
@JsonProperty("asset")
private Asset asset;
@NotNull
@Relationship(type = "ISSUED_BY")
@JsonProperty("organization")
private Organization organization;
或者(我假设这是带有 Spring 数据的 SDN 6,而不是 SDN 5 和 OGM?)您可以只删除自定义查询并使用 out-of-the-box SPEL 12=] 并且存储库方法将创建一个自动 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
的传出关系?
收藏是因为:
@false_memories 是正确的,但在这种情况下 WITH
子句不是必需的。如果您只是使用匹配子句中的变量,则不需要 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
子句与我的实际关系名称相匹配,因为它使它在查看原始结果时看起来更清晰一些。
neo4j @Query 注释的 Spring 数据不会填充任何由 @Relationship 注释标记的 child/parent 节点。
当在 Spring 数据存储库 class 中使用标准的 @CrudRepository 或 @PagingAndSortingRepository 查询时,Child/Parent 节点 class 将返回完整填充。
存储库接口
@Repository("trackerRepository")
public interface TrackerRepository extends PagingAndSortingRepository<Tracker, String> {
Tracker findByTrackerId(@NotNull String trackerId);
}
节点Class
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 使用方法 name/signature 生成的查询完美运行,returns 完全填充资产和组织节点。
但是,当使用 @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 注释定义的parent/child 节点?
使用@Query 编写自定义查询时,您需要准确指定要返回的内容:
@Relationship(type = "ASSIGNED_TO")
@JsonProperty("asset")
private Asset asset;
@NotNull
@Relationship(type = "ISSUED_BY")
@JsonProperty("organization")
private Organization organization;
或者(我假设这是带有 Spring 数据的 SDN 6,而不是 SDN 5 和 OGM?)您可以只删除自定义查询并使用 out-of-the-box SPEL 12=] 并且存储库方法将创建一个自动 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
的传出关系?
收藏是因为:
@false_memories 是正确的,但在这种情况下 WITH
子句不是必需的。如果您只是使用匹配子句中的变量,则不需要 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
子句与我的实际关系名称相匹配,因为它使它在查看原始结果时看起来更清晰一些。