将域对象作为参数传递给 Spring Data Neo4j 中的自定义 Cypher 查询

问题描述 投票:0回答:1

我正在编写 Spring Data Neo4j Web 应用程序。 我有这个域对象:

@Node("Person")
public class Person {
    
    @Id
    @GeneratedValue
    private String id;

(:Image) - [:DEPICTS] -> (:Person)
关系。

我需要计算描绘特定人物的图像。 这是我的尝试:

public interface ImageRepositoryNeo4j extends Neo4jRepository<Image, String> {
@Query("""
        MATCH (i:Image) -[:DEPICTS] -> (p:Person)
        WHERE p = $person
        RETURN count(i)
        """)
    // DSNT WORK
    public Integer countByPeopleContains(@Param("person") Person person);

但它总是返回0。

其他失败的尝试

@Query("""
        MATCH (i:Image)-[:DEPICTS]->(p:Person)
        WHERE p IN $people
        RETURN count(i)
        """)
    // DOESN'T WORK, 0 RESULTS
    public Integer countByPeopleContains(@Param("people") Collection<Person> people);

@Query("""
        MATCH (i:Image) -[:DEPICTS] -> (p:Person)
        WHERE ID(p) = $person.__id__
        RETURN count(i)
        """)
    // DSNT WORK
    public Integer countByPeopleContains(@Param("person") Person person);

@Query("""
        MATCH (i:Image) -[:DEPICTS] -> (p:Person)
        WHERE id(p)=$person
        RETURN count(i)
        """)
    // DSNT WORK
    public Integer countByPeopleContains(@Param("person") String personId);

@Query("""
        MATCH (i:Image) -[:DEPICTS] -> (p:Person {id: $person.__id__})
        RETURN count(i)
        """)
    // DSNT WORK, ALWAYS 0
    public Integer countByPeopleContains(@Param("person") Person person);

全部返回0。

这个是有效的,但是由于

fullName
不是唯一属性,因此它不适合领域逻辑:

@Query("""
        MATCH (i:Image) -[:DEPICTS] -> (p:Person {fullName: $person})
        RETURN count(i)
        """)
    // TODO: personFullname is not unique, use smth else
    public Integer countByPeopleContains(@Param("person") String personFullName);

如何在 Spring Data Neo4j 存储库中的自定义 Cypher 查询中使用域对象?

线索

Spring Data Neo4j 文档中,我发现的最接近我需要的是:

@Node
public final class Movie {

    @Id
    private final String title;
...
interface MovieRepository extends Neo4jRepository<Movie, String> {

    @Query("MATCH (m:Movie {title: $movie.__id__})\n"
           + "MATCH (m) <- [r:DIRECTED|REVIEWED|ACTED_IN] - (p:Person)\n"
           + "return m, collect(r), collect(p)")
    Movie findByMovie(@Param("movie") Movie movie);
}

但由于某种原因,它在我的情况下不起作用。也许那是因为我的id是

@GeneratedValue

java neo4j spring-data cypher spring-data-neo4j
1个回答
0
投票

我怀疑问题在于评估节点相等性。

而不是

WHERE p = $person
尝试
WHERE id(p) = id($person)

© www.soinside.com 2019 - 2024. All rights reserved.