我有一套PlayStation网络游戏和一组游戏文本本地化(游戏标题,游戏描述等)。我想将每个游戏与相应的区域设置相关联(" en"," fr"," de"例如),但我不确定正确的方法或者这是否正确使用Cypher的FOREACH条款。我使用Neo4jClient添加/更新游戏并添加/更新各自的区域设置。这是我到目前为止的代码:
client.Cypher
.ForEach("(game in {PSNGames} | MERGE (g:PSNGame {NPCOMMID : game.NPCOMMID}) SET g = game)")
.WithParams(new
{
PSNGames = games.ToList()
})
.ExecuteWithoutResults();
client.Cypher
.ForEach("(localized in {PSNGamesLocalized} | MERGE (l:PSNGameLocalized {NPCOMMID : localized.NPCOMMID}) SET l = localized)")
.WithParams(new
{
PSNGamesLocalized = localizedGames.ToList()
})
.ExecuteWithoutResults();
我的想法是做另一个ForEach
电话和MERGE
关系:
MATCH (g:PSNGame) WITH COLLECT(g) AS games
FOREACH (game IN games | MERGE game-[:LOCALE]->(l:PSNGameLocalized {NPCOMMID : game.NPCOMMID}))
但是,这会创建新的PSNGameLocalized标签,节点和属性:
Added 93 labels, created 93 nodes, set 93 properties, created 93 relationships, returned 0 rows in 326 ms
我一直在手动创建每个节点并添加/更新每个关系,这被证明非常慢。我喜欢批量交易的想法,以加快数据导入。如何在利用FOREACH
?
答案 0 :(得分:2)
在考虑解决问题之后,我想出了以下内容:
client.Cypher
.Match("(p:PSNProfile {PSNId : {profile}.PSNId})")
.ForEach(@"(game in {PSNGames} |
MERGE p-[:PLAYS {LastPlayed : game.LastUpdated}]->(g:PSNGame {NPCOMMID : game.NPCOMMID})-[:LOCALE]->(l:PSNGameLocalized {NPCOMMID : game.NPCOMMID})
SET g = game,
l = { NPCOMMID : game.NPCOMMID,
TitleName : game.TitleName,
TitleDetail : game.TitleDetail,
Locale : {locale}
})")
.WithParams(new
{
PSNGames = games.ToList(),
locale = locale,
profile = profile
})
.ExecuteWithoutResults();
这背后的关键是让Cypher处理foreach循环。我不再需要在C#端进行foreach循环。通过传递参数,我可以利用MERGE
命令动态创建/更新节点和关系。这种方法比我之前的方法快几个级别。我希望这可以帮助其他有类似问题的人。