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

aor9mmx1  于 2022-11-05  发布在  Spring
关注(0)|答案(1)|浏览(413)

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

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

类实体是这样的。

@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]时,它不会生成任何错误。因此,我知道错误是在哪里生成的,但我无法知道为什么会生成错误。
我能为它做些什么呢?

rdlzhqv9

rdlzhqv91#

在Cypher中不允许使用参数作为边界/限制值。(https://neo4j.com/docs/cypher-manual/current/syntax/parameters/
我建议在这里使用Neo4jTemplate。更具体的是关于Neo4jTemplate#findAll(Statement statement, Class<T> domainType)的东西。这个方法让你定义你自己的查询,手动创建,例如通过Cypher-DSL(https://github.com/neo4j-contrib/cypher-dsl/),以避免由于注入而导致的安全问题。
您 * 可以 * 做的其他事情是使用Neo4jClient,手动创建查询,例如再次使用Cypher-DSL,并使用Project实体的现有Map函数(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();

相关问题