获取节点按接近度排序,同级别按日期排序
Get nodes sorted by proximity and at the same level sort by date
我是 neo4j 的新手,我很难为我的查询获得良好的结果。我有下一个型号:
Player <- HAS_PLAYERS - Game
Node Player: playerId, name,...etc
Node Game: gameId, gameDate
Rel. HAS_PLAYERS: result
请注意,一个游戏可以有 1-4 名玩家。
我想查询以向以下命令的玩家推荐未来的对手:
以前的对手按 gameDate
排序(最近),然后对手的对手按 gameDate
排序。
例如:
PlayerA <- 2021/02/01 -> PlayerB*
PlayerA <- 2021/02/01 -> PlayerC*
PlayerA <- 2021/02/11 -> PlayerB
PlayerB <- 2021/02/04 -> PlayerC
PlayerB <- 2021/02/20 -> PlayerD
PlayerC <- 2021/02/15 -> PlayerD
PlayerC <- 2021/12/01 -> PlayerE
PlayerD <- 2021/02/07 -> PlayerE
PlayerD <- 2021/02/23 -> PlayerF
* = Same game
The result would be:
PlayerB
PlayerC
PlayerE
PlayerD
说明:
PlayerB
和PlayerC
曾经是对手,但PlayerB
是第一个,因为上一场比赛比PlayerC
更近。
PlayerE
和PlayerD
是对手,PlayerE
是之前,因为下一场比赛是在12月。
我有下一个查询,但我的问题是查询 returns 重复节点:
# Getting direct opponents
MATCH (p:Player {userId: "PlayerA"})<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(o:Player)
WITH p, o, g ORDER BY g.gameDate DESC
WITH p, COLLECT(o) AS opponents
# Getting opponents-of-opponents (ops)
MATCH (p)-[:HAS_PLAYERS*3]-(gops:Game)--(ops:Player)
WHERE p.userId <> ops.userId AND NOT ops IN opponents
# Trying to remove duplicated nodes
WITH DISTINCT ops, opponents, gops
WITH opponents, ops, gops ORDER BY gops.gameDate DESC
# Concat both lists: opponents and opponents-of-opponents
WITH REDUCE(s = opponents, o2 IN COLLECT(ops) | s + o2) as listAllOpponents
UNWIND listAllOpponents as opPlayer
RETURN opPlayer
它returns类似于:
PlayerB
PlayerC
PlayerD
PlayerE
PlayerD
如有任何帮助,我们将不胜感激。
当您聚合节点时,它不会删除重复项,因此添加关键字“distinct”将修复它。代替 COLLECT(o),使用 COLLECT(DISTINCT o) 作为对手并使用 COLLECT(DISTINCT ops)。
// Getting direct opponents
MATCH (p:Player {userId: "34618"})<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(o:Player)
WITH p, o, g ORDER BY g.gameDate DESC
WITH p, COLLECT(DISTINCT o) AS opponents
// Getting opponents-of-opponents (ops)
MATCH (p)-[:HAS_PLAYERS*3]-(gops:Game)--(ops:Player)
WHERE p.userId <> ops.userId AND NOT ops IN opponents
// Trying to remove duplicated nodes
WITH DISTINCT ops, opponents, gops
WITH opponents, ops, gops ORDER BY gops.gameDate DESC
// Concat both lists: opponents and opponents-of-opponents
WITH REDUCE(s = opponents, o2 IN COLLECT(DISTINCT ops) | s + o2) as listAllOpponents
UNWIND listAllOpponents as opPlayer
RETURN opPlayer
Result:
PlayerB
PlayerC
PlayerE
PlayerD
这是我的解决方案:
# Getting direct opponents
MATCH (p:Player {userId: "PlayerA"})<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(o:Player)
WITH p, o, max(g.gameDate) as maxDate
WITH p, o ORDER BY maxDate DESC
WITH p, COLLECT(o) AS opponents
# Getting opponents-of-opponents (ops)
OPTIONAL MATCH (p)-[:HAS_PLAYERS*3]-(gops:Game)--(ops:Player)
WHERE p.userId <> ops.userId AND NOT ops IN opponents
WITH opponents, ops, max(gops.start) as maxDate
WITH opponents, ops ORDER BY maxDate DESC
WITH opponents, COLLECT(ops) AS opponentsOfOpponents
# Concat both lists: opponents and opponents-of-opponents
UNWIND (opponents + opponentsOfOpponents) AS player
RETURN player
我是 neo4j 的新手,我很难为我的查询获得良好的结果。我有下一个型号:
Player <- HAS_PLAYERS - Game
Node Player: playerId, name,...etc
Node Game: gameId, gameDate
Rel. HAS_PLAYERS: result
请注意,一个游戏可以有 1-4 名玩家。
我想查询以向以下命令的玩家推荐未来的对手:
以前的对手按 gameDate
排序(最近),然后对手的对手按 gameDate
排序。
例如:
PlayerA <- 2021/02/01 -> PlayerB*
PlayerA <- 2021/02/01 -> PlayerC*
PlayerA <- 2021/02/11 -> PlayerB
PlayerB <- 2021/02/04 -> PlayerC
PlayerB <- 2021/02/20 -> PlayerD
PlayerC <- 2021/02/15 -> PlayerD
PlayerC <- 2021/12/01 -> PlayerE
PlayerD <- 2021/02/07 -> PlayerE
PlayerD <- 2021/02/23 -> PlayerF
* = Same game
The result would be:
PlayerB
PlayerC
PlayerE
PlayerD
说明:
PlayerB
和PlayerC
曾经是对手,但PlayerB
是第一个,因为上一场比赛比PlayerC
更近。
PlayerE
和PlayerD
是对手,PlayerE
是之前,因为下一场比赛是在12月。
我有下一个查询,但我的问题是查询 returns 重复节点:
# Getting direct opponents
MATCH (p:Player {userId: "PlayerA"})<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(o:Player)
WITH p, o, g ORDER BY g.gameDate DESC
WITH p, COLLECT(o) AS opponents
# Getting opponents-of-opponents (ops)
MATCH (p)-[:HAS_PLAYERS*3]-(gops:Game)--(ops:Player)
WHERE p.userId <> ops.userId AND NOT ops IN opponents
# Trying to remove duplicated nodes
WITH DISTINCT ops, opponents, gops
WITH opponents, ops, gops ORDER BY gops.gameDate DESC
# Concat both lists: opponents and opponents-of-opponents
WITH REDUCE(s = opponents, o2 IN COLLECT(ops) | s + o2) as listAllOpponents
UNWIND listAllOpponents as opPlayer
RETURN opPlayer
它returns类似于:
PlayerB
PlayerC
PlayerD
PlayerE
PlayerD
如有任何帮助,我们将不胜感激。
当您聚合节点时,它不会删除重复项,因此添加关键字“distinct”将修复它。代替 COLLECT(o),使用 COLLECT(DISTINCT o) 作为对手并使用 COLLECT(DISTINCT ops)。
// Getting direct opponents
MATCH (p:Player {userId: "34618"})<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(o:Player)
WITH p, o, g ORDER BY g.gameDate DESC
WITH p, COLLECT(DISTINCT o) AS opponents
// Getting opponents-of-opponents (ops)
MATCH (p)-[:HAS_PLAYERS*3]-(gops:Game)--(ops:Player)
WHERE p.userId <> ops.userId AND NOT ops IN opponents
// Trying to remove duplicated nodes
WITH DISTINCT ops, opponents, gops
WITH opponents, ops, gops ORDER BY gops.gameDate DESC
// Concat both lists: opponents and opponents-of-opponents
WITH REDUCE(s = opponents, o2 IN COLLECT(DISTINCT ops) | s + o2) as listAllOpponents
UNWIND listAllOpponents as opPlayer
RETURN opPlayer
Result:
PlayerB
PlayerC
PlayerE
PlayerD
这是我的解决方案:
# Getting direct opponents
MATCH (p:Player {userId: "PlayerA"})<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(o:Player)
WITH p, o, max(g.gameDate) as maxDate
WITH p, o ORDER BY maxDate DESC
WITH p, COLLECT(o) AS opponents
# Getting opponents-of-opponents (ops)
OPTIONAL MATCH (p)-[:HAS_PLAYERS*3]-(gops:Game)--(ops:Player)
WHERE p.userId <> ops.userId AND NOT ops IN opponents
WITH opponents, ops, max(gops.start) as maxDate
WITH opponents, ops ORDER BY maxDate DESC
WITH opponents, COLLECT(ops) AS opponentsOfOpponents
# Concat both lists: opponents and opponents-of-opponents
UNWIND (opponents + opponentsOfOpponents) AS player
RETURN player