neo4j 如何从CYPHER查询的COLLECT()子句中删除包含NULL的对象?

wlp8pajw  于 2023-06-22  发布在  其他
关注(0)|答案(2)|浏览(167)

我在这个Cypher查询中遇到了以下问题。总体结果按预期在对象数组中返回。但是,collect()子句给我带来了一些麻烦。
如果user没有myFriends,也没有theirFriends,则应返回空数组。否则,如果myFriends和/或theirFriends具有值,则它应该是组合好友的对象的单个数组,具有相应好友的id属性。

查询:

MATCH (user:User)
WHERE user.id IN ['1', '2', '3']
OPTIONAL MATCH (user)-[:HAS_FRIEND]->(myFriends:User)
OPTIONAL MATCH (user)<-[:HAS_FRIEND]-(theirFriends:User)
OPTIONAL MATCH (user)-[:HAS_TEACHER]->(myTeachers:User)
RETURN {
  name: user.name,
  friends: collect({id: myFriends.id}) + collect({id: theirFriends.id}),
  teachers: collect({id: myTeachers.id})
}

结果:

[
  {
    name: 'Joe',
    friends: [{id: null}, {id: null}],
    teachers: [{id: null}]
  }, ...
]

期望结果:

[
  {
    name: 'Joe',
    friends: [],
    teachers: []
  }, {
    name: 'Jen',
    friends: [{id: '4'}, {id: '6'}, {id: '7'}],
    teachers: [{id: '8'}, {id: '9'}]
  }
]
qxsslcnc

qxsslcnc1#

[更新]
关于您的特定数据模型的一个非常好的地方是:你可以用一个 * 无向 * 关系模式得到所有的myFriendstheirFriends元素:(user)-[:HAS_FRIEND]-(f)
例如:

MATCH (user:User)
WHERE user.id IN ['1', '2', '3']
OPTIONAL MATCH (user)-[:HAS_FRIEND]-(f:User)
OPTIONAL MATCH (user)-[:HAS_TEACHER]->(t:User)
RETURN {
  name: user.name,
  friends: COLLECT(DISTINCT f{.id}),
  teachers: COLLECT(t{.id})
}

因此,不需要列表连接。此外,DISTINCT选项会删除重复的friends元素。

  • 顺便说一下,这个查询还使用了@P.S.建议的整洁Map投影语法,避免了null值。
x6h2sr28

x6h2sr282#

一个优雅的解决方案,使用Map投影并保留OPTIONAL MATCH子句。

MATCH (user:User)
WHERE user.id IN ['1', '2', '3']
OPTIONAL MATCH (user)-[:HAS_FRIEND]->(myFriends:User)
OPTIONAL MATCH (user)<-[:HAS_FRIEND]-(theirFriends:User)
OPTIONAL MATCH (user)-[:HAS_TEACHER]->(myTeachers:User)
RETURN {
  name: user.name,
  friends: collect(myFriends {.id}) + collect(theirFriends {.id}),
  teachers: collect(myTeachers {.id})
}

相关问题