Spring Data Neo4j - 无法从自定义查询中获取结果

Spring Data Neo4j - can't get result from custom query

我写了下面的代码来检索 class 个实体。

@Repository
public interface ClassRepository extends ReactiveNeo4jRepository<Class, Long> {
    @Query("MATCH (project: Project) WHERE $pid in project.pids " +
            "MATCH (c: Class {name: $name})-[:relates*1..$depth]-(target: Class) " +
            "RETURN target")
    Flux<Class> findClassByName(@Param("name") String name, Long pid, @Param("depth") Long depth);
}

而Class实体就是这个。

@Node("Class")
@ToString
@Getter
@Setter
public class Class {
    @GeneratedValue
    @Id
    private Long id;
    private String url;
    private String name;
    private Boolean isAbstract;
    private Boolean isStatic;

    @Relationship(type="belongs_to_package", direction = Relationship.Direction.INCOMING)
    private Package aPackage;

    @Relationship(type = "relates", direction = Relationship.Direction.INCOMING)
    private Set<ClassRelationship> classRelates = new HashSet<>();
    @Relationship(type = "relates", direction = Relationship.Direction.INCOMING)
    private Set<InterfaceRelationship> interfaceRelates = new HashSet<>();
    @Relationship(type = "nested", direction = Relationship.Direction.INCOMING)
    private Set<Class> nested = new HashSet<>();

    public Class(String url, String name, Boolean isAbstract, Boolean isStatic, Package aPackage) {
        this.url = url;
        this.name = name;
        this.isAbstract = isAbstract;
        this.isStatic = isStatic;
        this.aPackage = aPackage;
    }
}

但是它会产生这样的错误...

org.neo4j.driver.exceptions.ClientException: Parameter maps cannot be used in MATCH patterns (use a literal map instead, eg. "{id: {param}.id}") (line 1, column 97 (offset: 96))
"MATCH (project: Project) WHERE $pid in project.pids MATCH (c: Class {name: $name})-[:relates*1..$depth]-(target: Class) RETURN target"

当我将 [:relates*1..$depth] 更改为 [:relates] 时,它不会生成任何错误。所以我知道错误在哪里产生但我不知道为什么会产生错误..
我能为它做什么?

在 Cypher 中不允许使用参数作为 boundary/limit 值。 (https://neo4j.com/docs/cypher-manual/current/syntax/parameters/)

我建议在这里使用 Neo4jTemplateNeo4jTemplate#findAll(Statement statement, Class<T> domainType) 附近的更具体的内容。 此方法让您定义自己的查询,手动创建,例如通过 Cypher-DSL (https://github.com/neo4j-contrib/cypher-dsl/) 来避免由于注入引起的安全问题。

可以做的其他事情是使用Neo4jClient,手动创建查询,例如再次使用 Cypher-DSL,并为您的 Project 实体 (https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#neo4j-client.result-objects.mapping-functions)

使用现有的映射函数

简而言之,像这样(没有 Cypher-DSL 部分):

BiFunction<TypeSystem, MapAccessor, Movie> mappingFunction = neo4jMappingContext.getRequiredMappingFunctionFor(Project.class);
Project project = client
    .query("<your statement>")
    .fetchAs(Project.class).mappedBy((TypeSystem t, Record record) -> {
       return record.get("target")
            .asList(project -> mappingFunction.apply(t, project));
    })
    .one();