neo4j 如何从Cypher的集合中找到包含数组作为属性的对象的索引?

o8x7eapl  于 2023-04-30  发布在  其他
关注(0)|答案(2)|浏览(150)

我试图在一个自定义对象的集合中找到一个项目的索引(所以不是一个节点的集合)。我使用的是apoc.coll.indexOf(collection, object),但它返回的是-1而不是实际的索引。
下面的查询显示了该问题。第一个查询创建了两个测试节点,每个节点都有一个名为someArray的布尔数组。第二个查询匹配所有具有给定标签的节点,将它们收集到名为collection的变量中,最后尝试获取具有相同someArray字段的对象的索引作为空数组。我期望它返回01(取决于集合的排序方式),但它返回-1

CREATE (test:Test { someArray: [true, false, true] })
CREATE (test2:Test { someArray: [] })
MATCH (n:Test)

WITH COLLECT({
    someArray: n.someArray
}) as collection

RETURN apoc.coll.indexOf(collection, { someArray: [] }) // Returns -1

在这种情况下,如何找到正确的索引?如果这是预期的行为(例如,通过引用比较数组),您可以指向文档页面吗?
(this Neo4j 4(四)

vxqlmq5t

vxqlmq5t1#

这似乎是由apoc中的一个奇怪的bug引起的。coll.indexOf.
此查询:

MATCH (n:Test)
WITH COLLECT({
    someArray: n.someArray
}) as collection
RETURN collection

返回以下内容:

[{someArray: [true, false, true]}, {someArray: []}]

如果你把这个列表硬编码到这个查询中(我在neo4j 5上测试过)。5):

RETURN apoc.coll.indexOf([{someArray: [true, false, true]}, {someArray: []}], {someArray: []})

结果是1
因此,apoc.coll.indexOf意外地将collection与“相同”的硬编码列表区别对待。
您应该创建一个neo4j issue关于这个奇怪的行为。
[更新]
解决方法(其中测试值作为$val parameter传递):

MATCH (n:Test)
WITH COLLECT(
  {someArray: n.someArray}
) AS collection
RETURN [i IN RANGE(0, SIZE(collection)-1) WHERE collection[i] = $val | i] AS result

result是一个可能为空的匹配索引列表。这个查询类似于@CharchitKapoor的查询,但我们返回所有匹配的索引。

wn9m85ua

wn9m85ua2#

正如cybersam提到的,这是APOC函数的问题,现在,你可以尝试这个解决方法,而不使用Apoc:

MATCH (n:Test)
WITH COLLECT({
    someArray: n.someArray
}) as collection
WITH [x IN range(0, size(collection) - 1) WHERE collection[x].someArray = []] AS indexes
RETURN CASE WHEN size(indexes) = 0 THEN -1 ELSE indexes[0] END AS index

相关问题