Neo4j APOC自定义函数未找到时挂起

ryoqjall  于 2023-08-04  发布在  其他
关注(0)|答案(3)|浏览(123)

我编写了以下自定义函数,它执行复杂的搜索并返回ID列表。下面是一个简化版本:

CALL apoc.custom.declareFunction('test()::LIST OF INTEGER?', '
    MATCH (m:Movie)
    WITH m.id AS id
    LIMIT 1
    RETURN id
')

字符串
该函数用于以下查询:

MATCH (m:Movie)
WHERE m.id IN custom.test()
RETURN m.title AS title


使用RETURN custom.test() as ids测试函数时,执行结果为[{'ids': [57]}]
在函数没有找到任何东西的情况下(对于简化版本,我将LIMIT 1替换为LIMIT 0),我希望函数返回[{'ids': []}]。然而,相反,它只是挂起
我尝试将返回类型定义为LIST OF INTEGERLIST OF INTEGER?
这是APOC bug吗?如何解决这个问题?

i7uq4tfw

i7uq4tfw1#

将自定义函数的查询更改为:

OPTIONAL MATCH (m:Movie)
RETURN m.id AS id

字符串
如果没有Movie节点,OPTIONAL MATCH将导致从您的自定义函数返回[NULL],在这种情况下,您的测试查询将按预期工作(即不返回结果)。
您可以通过在查询中将:Movie替换为:FooBar(而不是使用LIMIT 0)来测试自定义函数在没有结果时是否正常工作。

8nuwlpux

8nuwlpux2#

试试这个:

UNWIND custom.test() as id
MATCH (m: Movie) where m.id = id
RETURN m.title AS title

字符串
UNWIND就像一个for循环,所以它会修复你的代码,不会挂起。请测试一下。

mpgws1up

mpgws1up3#

虽然将OPTIONAL添加到MATCH语句确实有助于避免挂起,但这种方法仅适用于MATCH,而不适用于CALL
我提出一个通用的解决方案:在查询的最后,我们应该使用COLLECT()将所有结果收集到一个数组中,并使用参数forceSingle = true创建函数:

CALL apoc.custom.declareFunction('test(limit :: INTEGER)::LIST OF INTEGER?', '
MATCH (m:Movie)
WITH m.id AS id
LIMIT $limit
RETURN COLLECT(id)
', true)

字符串
现在,调用函数RETURN custom.test(0) as ids返回[{'ids': []}]

相关问题