当前位置: 首页 > 知识库问答 >
问题:

Spring引导Neo4j-查询深度无法正常工作

刘松
2023-03-14

太长别读:@Depth(value=-1)抛出空指针,忽略1以上的其他值

在我的Spring Boot with Neo4j项目中,我有3个简单的实体与关系:

@NodeEntity
data class Metric(
        @Id @GeneratedValue val id: Long = -1,
        val name: String = "",
        val description: String = "",
        @Relationship(type = "CALCULATES")
        val calculates: MutableSet<Calculable> = mutableSetOf()
) {
    fun calculates(calculable: Calculus) = calculates.add(calculable)
    fun calculate() = calculates.map { c -> c.calculate() }.sum()
}

interface Calculable {
    fun calculate(): Double
}

@NodeEntity
data class Calculus(
        @Id @GeneratedValue val id: Long = -1,
        val name: String = "",
        @Relationship(type = "LEFT")
        var left: Calculable? = null,
        @Relationship(type = "RIGHT")
        var right: Calculable? = null,
        var operator: Operator? = null
) : Calculable {
    override fun calculate(): Double =
            operator!!.apply(left!!.calculate(), right!!.calculate())
}

@NodeEntity
data class Value(
        @Id @GeneratedValue val id: Long = -1,
        val name: String = "",
        var value: Double = 0.0
) : Calculable {
    override fun calculate(): Double = value
}

enum class Operator : BinaryOperator<Double>, DoubleBinaryOperator {//not relevant}

我创建了一个简单的图,如下所示:

使用以下存储库:

@Repository
interface MetricRepository : Neo4jRepository<Metric, Long>{
    @Depth(value = 2)
    fun findByName(name: String): Metric?
}

@Repository
interface CalculusRepository : Neo4jRepository<Calculus, Long>{
    fun findByName(name: String): Calculus?
}

@Repository
interface ValueRepository : Neo4jRepository<Value, Long>{
    fun findByName(name: String): Value?
}

以及以下代码:

// calculus
val five = valueRepository.save(Value(
        name = "5",
        value = 5.0
))

val two = valueRepository.save(Value(
        name = "2",
        value = 2.0
))

val fiveTimesTwo = calculusRepository.save(Calculus(
        name = "5 * 2",
        operator = Operator.TIMES,
        left = five,
        right = two
))

println("---")
println(fiveTimesTwo)
val fromRepository = calculusRepository.findByName("5 * 2")!!
println(fromRepository) // sometimes has different id than fiveTimesTwo
println("5 * 2 = ${fromRepository.calculate()}")
println("--- \n")


// metric
val metric = metricRepository.save(Metric(
        name = "Metric 1",
        description = "Measures a calculus",
        calculates = mutableSetOf(fromRepository)
))
metricRepository.save(metric)

println("---")
println(metric)
val metricFromRepository = metricRepository.findByName("Metric 1")!!
println(metricFromRepository) // calculates node is partially empty
println("--- \n")

要检索与上图所示相同的图表(取自实际的neo4j仪表板),我执行metricRepository.findByName("Metric 1"),其中包含@Depth(value=2),然后打印保存的度量和检索的度量:

Metric(id=9, name=Metric 1, description=Measures a calculus, calculates=[Calculus(id=2, name=5 * 2, left=Value(id=18, name=5, value=5.0), right=Value(id=1, name=2, value=2.0), operator=TIMES)])

Metric(id=9, name=Metric 1, description=Measures a calculus, calculates=[Calculus(id=2, name=5 * 2, left=null, right=null, operator=TIMES)])

无论深度的值如何,我都无法获取包含所有子节点的Metric节点,它检索一级深度max并在叶节点上返回null。

我在文档中读到深度=-1检索完全解析的节点,但这样做会导致findByName()方法失败,指针为空:kotlin。KotlinNullPointerException:null

这是我咨询过的资源列表和包含完整代码的工作GitHub存储库:

  • GitHub回购
  • Spring Data Neo4j参考文档
  • Neo4j-OGM文档

最终注释:

  • 实体都有默认参数,因为静态编程语言会创建一个空构造函数,我认为OGM需要它
  • 我也尝试过自定义查询,但无法指定深度值,因为有不同的关系,可以在不同的级别
  • 要使用我链接的GitHub存储库,您必须安装Neo4j,存储库有一个包含所有代码的stackoverflow问题分支。

版本:

  • Spring护套:2.3.0。构建快照

感谢您的帮助,欢迎所有反馈!

共有1个答案

沈翰
2023-03-14

问题不在于查询深度,而在于模型。度量实体与可计算实体有关系,但可计算实体本身没有定义关系。Spring数据无法扫描可计算接口的所有可能实现,以了解它们之间的关系。如果您更改了度量标准。将类型计算为可变表集

要查看发送到服务器的Cypher请求,可以添加日志记录。数量组织。neo4j。ogm。驱动程序。螺栓=调试应用程序。属性

变更前的请求:

MATCH (n:`Metric`) WHERE n.`name` = $`name_0` WITH n RETURN n,[ [ (n)->[r_c1:`CALCULATES`]->(x1) | [ r_c1, x1 ] ] ], ID(n) with params {name_0=Metric 1}

更改后的请求:

MATCH (n:`Metric`) WHERE n.`name` = $`name_0` WITH n RETURN n,[ [ (n)->[r_c1:`CALCULATES`]->(c1:`Calculus`) | [ r_c1, c1, [ [ (c1)-[r_l2:`LEFT`]-(v2:`Value`) | [ r_l2, v2 ] ], [ (c1)-[r_r2:`RIGHT`]-(v2:`Value`) | [ r_r2, v2 ] ] ] ] ] ], ID(n) with params {name_0=Metric 1}
 类似资料:
  • 计划程序的设置: 和@enableScheduling在类中使用@configuration。 问题是fixedDelay正确工作两次,然后在迭代之间暂停1.5分钟。我在计划注释中尝试过fixedRate或cron,但都没有帮助。 方法在调度任务中的工作时间为100ms,项目有足够的内存,但调度程序的工作速度很慢。

  • 所以我有一个带有日期时间值的输入(从DB获取值),我使用jQuery日期时间选择器来更改日期/时间。 这是我的输入 这是我的Datetimepicker配置: 使用此配置,Datetimepicker将始终从现在开始的日期时间作为默认值。如果我删除选项,我可以在输入中看到数据库中的实际日期/时间。 信息:我在数据库中的日期不是weekend,与现在一样新()。 所以我的问题是,我怎么能使用Date

  • 问题内容: 我有一个课程,如何让@JsonIgnore工作。即使将注释放在此处,它也不会影响输出。我正在使用杰克逊。 这是我的Controller方法: 这是我的servlet-context.xml: 问题答案: 我终于找到了解决方案。我将导入声明从 至 基本上,您必须确保在所有地方都使用相同的类。

  • } 这是我的配置。但似乎/用户/无法被任何人访问。 每当我输入“. hasRole(“RoleName”)”时,它只会拒绝该角色的访问。我得到一个{“时间戳”:1526671066818,“状态”: 403,“错误”:“禁止”,“消息”:“拒绝访问”,“路径”:“/用户”} 从那。 我想要的是,一些请求只允许“USER”访问,例如:“/entrysheet”,“/datasheet”等,而“ADM

  • 问题内容: 我正在尝试使用带注释的TX Spring支持。 应用程序上下文XML: 实际代码: 调用代码: 它给出了 FALSE。 我究竟做错了什么? 问题答案: 您应该在配置中添加它 在您的RepositoryClass上添加一个接口 这在你的测试课中 请参阅本教程。

  • 我是neo4j spring数据的新手,我尝试执行的查询不是在我的spring boot应用程序上工作,而是在neo4j web界面上工作。 我在数据库上有3个节点:“Oracle”、“Java”和“Cloud”我正在尝试运行的查询: 因此,使用neo4j web界面,如果我输入“CL”,它将返回“Oracle”和“Cloud”,这是正确的。 使用spring数据,我得到了所有3个结果,这是错误的