我正在开发一个小型的推荐系统,为下一场比赛推荐玩家。推荐包括首先关注的玩家,然后是玩家之前玩过的玩家,按游戏数量排序。
结果将是Player, is_followed (true|false), GameIds
我有Player和Game节点,它们的关系是Game -[:HAS_PLAYER]-> Player和
Player节点与Player -[:FOLLOWS]-> Player直接相关。
我的测试DB:
CREATE (superman:Player {playerID: 'superman', name:'Superman', sanitizedName: 'superman'})
CREATE (batman:Player {playerID: 'batman', name:'Batman', sanitizedName: 'batman'})
CREATE (catwoman:Player {playerID: 'catwoman', name:'Catwoman', sanitizedName: 'catwoman'})
CREATE (lois:Player {playerID: 'lois', name:'Lois Lane', sanitizedName: 'lois lane'})
CREATE (wonderwoman:Player {playerID: 'wonderwoman', name:'Wonder Woman', sanitizedName: 'wonder woman'})
CREATE (aquaman:Player {playerID: 'aquaman', name:'Aquaman', sanitizedName: 'aquaman'})
CREATE (flash:Player {playerID: 'flash', name:'Flash', sanitizedName: 'flash'})
CREATE (cyborg:Player {playerID: 'cyborg', name:'Cyborg', sanitizedName: 'cyborg'})
CREATE (joker:Player {playerID: 'joker', name:'Joker', sanitizedName: 'joker'})
CREATE (lex:Player {playerID: 'lex', name:'Lex Luthor', sanitizedName: 'lex luthor'})
CREATE (green:Player {playerID: 'green', name:'Green Lantern', sanitizedName: 'green lantern'})
CREATE (g1:Game {gameId:"game-1"})
CREATE (g1)-[:HAS_PLAYERS {teamId:"0"}]->(superman)
CREATE (g1)-[:HAS_PLAYERS {teamId:"0"}]->(aquaman)
CREATE (g1)-[:HAS_PLAYERS {teamId:"1"}]->(batman)
CREATE (g1)-[:HAS_PLAYERS {teamId:"1"}]->(flash)
CREATE (g2:Game {gameId:"game-2"})
CREATE (g2)-[:HAS_PLAYERS {teamId:"0"}]->(superman)
CREATE (g2)-[:HAS_PLAYERS {teamId:"0"}]->(batman)
CREATE (g2)-[:HAS_PLAYERS {teamId:"1"}]->(joker)
CREATE (g2)-[:HAS_PLAYERS {teamId:"1"}]->(lex)
CREATE (g3:Game {gameId:"game-3"})
CREATE (g3)-[:HAS_PLAYERS {teamId:"0"}]->(flash)
CREATE (g3)-[:HAS_PLAYERS {teamId:"0"}]->(lois)
CREATE (g3)-[:HAS_PLAYERS {teamId:"1"}]->(wonderwoman)
CREATE (g3)-[:HAS_PLAYERS {teamId:"1"}]->(aquaman)
CREATE (g4:Game {gameId:"game-4"})
CREATE (g4)-[:HAS_PLAYERS {teamId:"0"}]->(joker)
CREATE (g4)-[:HAS_PLAYERS {teamId:"0"}]->(cyborg)
CREATE (g4)-[:HAS_PLAYERS {teamId:"1"}]->(wonderwoman)
CREATE (g4)-[:HAS_PLAYERS {teamId:"1"}]->(green)
CREATE (g5:Game {gameId:"game-5"})
CREATE (g5)-[:HAS_PLAYERS {teamId:"0"}]->(catwoman)
CREATE (g5)-[:HAS_PLAYERS {teamId:"1"}]->(green)
CREATE (batman)-[:FOLLOWS]->(superman)
CREATE (batman)-[:FOLLOWS]->(catwoman)
CREATE (lex)-[:FOLLOWS]->(joker)
CREATE (joker)-[:FOLLOWS]->(lex)
;

有了这些数据,我想向蝙蝠侠推荐他的下一场比赛的球员,结果必须是:
superman true [game-1, game-2]
catwoman true []
aquaman false [game-1]
flash false [game-1]
joker false [game-2]
lex false [game-2]更新:我有下一个问题,但是下面的玩家不见了:
MATCH (u:Player{playerID:"batman"})
OPTIONAL MATCH (u)<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(p:Player)
RETURN p, EXISTS((u)-[:FOLLOWS]->(p)) AS is_followed, COUNT(g) AS num_games, collect(g) AS games
ORDER BY num_games DESC谢谢!
更新2
这种方法可以更“可读性”,但性能比公认的答案差得多。
MATCH (u:Player{playerID:"batman"})
CALL {
WITH u
MATCH (u)<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(p:Player)
RETURN p
UNION
WITH u
MATCH (u)-[:FOLLOWS]->(p:Player)
RETURN p
}
WITH p,
EXISTS((u)-[:FOLLOWS]->(p)) AS is_followed,
[(u)<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(p) | g.gameId] AS games
RETURN p.name, is_followed, size(games) AS num_games, games
ORDER BY num_games DESC发布于 2021-05-05 01:27:38
你没有得到猫女,因为你只通过:游戏节点匹配:玩家与蝙蝠侠相关,你还需要匹配(u:玩家{playerID:“蝙蝠侠”})-:跟随->(p:玩家)
MATCH (u:Player{playerID:"batman"})
OPTIONAL MATCH (u)<-[:HAS_PLAYERS]-(g:Game)-[:HAS_PLAYERS]->(p:Player)
RETURN p.playerID, EXISTS((u)-[:FOLLOWS]->(p)) AS is_followed, COUNT(g) AS num_games, collect(g.gameId) AS games
ORDER BY num_games DESC
union
match (u:Player{playerID:"batman"})-[:FOLLOWS]->(p:Player)
where not exists( (u)<-[:HAS_PLAYERS]-(:Game)-[:HAS_PLAYERS]->(p:Player) )
RETURN p.playerID, true AS is_followed, 0 AS num_games, [] AS games

(我想不出没有联合的方法,但这可能是可能的)
https://stackoverflow.com/questions/67385780
复制相似问题