Neo4jclient - 在一个批次中插入多个关系

时间:2014-09-24 08:51:55

标签: neo4j neo4jclient

我有一个用例,每当用户看到这样的照片时,我就会创建一个新的关系:

var dateParams = new { Date = DateTime.Now.ToString() };

            graphClient.Cypher
                 .Match("(user:User), (photo:Photo)")
                 .Where((UserEntity user) => user.Id == userId)
                 .AndWhere((PhotoEntity photo) => photo.Id == photoId)
                 .CreateUnique("user-[:USER_SEEN_PHOTO {params}]->photo")
                 .WithParam("params", dateParams)
                 .ExecuteWithoutResults();

对于许多并发用户而言,这种情况经常会发生,所以我需要能够排队一些写操作并一次执行它们。不幸的是,我无法通过Neo4jClient以最有效的方式找到有关如何做到这一点的好信息所以所有建议都将非常感激:)

---更新---

所以我尝试了不同的组合,但我仍然没有找到任何有用的东西。下面的查询给我一个“PatternException:Unbound pattern!”?

  var query = graphClient.Cypher;
            for (int i = 0; i < seenPhotosList.Count; i++)
            {
                query = query.CreateUnique("(user" + i + ":User {Id : {userId" + i + "} })-[:USER_SEEN_PHOTO]->(photo" + i + ":Photo {Id : {photoId" + i + "} })")
                    .WithParam("userId" + i, seenPhotosList[i].UserId)
                    .WithParam("photoId" + i, seenPhotosList[i].PhotoId);
            }
            query.ExecuteWithoutResults();

我还尝试将CreateUnique更改为Merge,该查询无异常执行但是创建新节点而不是连接现有节点?

 var query = graphClient.Cypher;
            for (int i = 0; i < seenPhotosList.Count; i++)
            {
                query = query.Merge("(user" + i + ":User {Id : {userId" + i + "} })-[:USER_SEEN_PHOTO]->(photo" + i + ":Photo {Id : {photoId" + i + "} })")
                    .WithParam("userId" + i, seenPhotosList[i].UserId)
                    .WithParam("photoId" + i, seenPhotosList[i].PhotoId);
            }
            query.ExecuteWithoutResults();

2 个答案:

答案 0 :(得分:1)

我使用Batch Insert设置了5种关系。它运行速度非常快,但不确定如何在多用户环境中管理中断。您需要提前知道nodeID,然后为API请求创建一个看起来像这样的字符串......

[{"method":"POST","to":"/node/222/relationships","id":222,"body":{"to":"26045","type":"mother"}},
{"method":"POST","to":"/node/291/relationships","id":291,"body":{"to":"26046","type":"mother"}},
{"method":"POST","to":"/node/389/relationships","id":389,"body":{"to":"26047","type":"mother"}},
{"method":"POST","to":"/node/1031/relationships","id":1031,"body":{"to":"1030","type":"wife"}},
{"method":"POST","to":"/node/1030/relationships","id":1030,"body":{"to":"1031","type":"husband"}},
{"method":"POST","to":"/node/1034/relationships","id":1034,"body":{"to":"26841","type":"father"}},
{"method":"POST","to":"/node/34980/relationships","id":34980,"body":{"to":"26042","type":"child"}}]

我还将其分解为合理大小的迭代请求,以避免内存挑战。但迭代运行速度非常快,无法设置所需的字符串。获取nodeID还需要迭代,因为Neo4j限制了返回1000的节点数。这是Neo4j的一个缺点,它是基于可视化关注点设计的(谁可以研究10000个节点的图片?)而不是编码问题,比如我们正在讨论的问题

答案 1 :(得分:0)

我不相信Neo4j / cypher有任何内置的方式来执行你要求的东西。你可以做的是用排队系统为你做一些事情。这里有一个关于在Ruby中进行可伸缩写入的blog post,你可以用你的语言来实现批量插入/更新。