Neo4j:合并复制查询中三个节点之一

时间:2018-02-27 15:54:10

标签: c# neo4j cypher neo4jclient

正如我在另一篇文章中所述,我正在从SQL Server迁移到Neo4j,所以我正在努力学习。我一直在搜索StackOverflow并谷歌回答我的问题,但我偶然发现了一个没有意义的查询的奇怪结果。

C#代码:

public void AddMarketInfo(MarketInfo mi)
{
    Bid bid = mi.Bid;
    Ask ask = mi.Ask;

    var query = clientConnection.Cypher
        .Merge("(newbid:Bid { ID: {bID} })")
        .OnCreate()
        .Set("newbid = {bid}")
            .WithParams(new
            {
                bID = bid.ID,
                bid
            })
        .Merge("(newask:Ask { ID: {aID} })")
        .OnCreate()
        .Set("newask = {ask}")
            .WithParams(new
            {
                aID = ask.ID,
                ask
            })
        .Merge("(newMarketInfo:MarketInfo { ID: {id}, ASK: {askID}, BID: {bidID} })")
        .OnCreate()
        .Set("newMarketInfo = {mi}")
            .WithParams(new
            {
                id = mi.ID,
                bidID = bid.ID,
                askID = ask.ID,
                mi
            })
    .CreateUnique("(newask)-[rA:Ask_Input_Data]->(newMarketInfo)")
    .CreateUnique("(newbid)-[rB:Bid_Input_Data]->(newMarketInfo)");
    query.ExecuteWithoutResults();
}

我正在调试该程序,因此该语句多次在同一数据上执行。是的,我现在要进入数据库并删除所有节点。

创建“出价”节点和“询问”节点时,它成功与现有节点合并,但“MarketInfo”节点正在重复。

有什么想法?

enter image description here

enter image description here

编辑2:修改查询

所以我在neo4j文档中做了更多的阅读:

https://neo4j.com/docs/developer-manual/current/cypher/clauses/merge/#query-merge-on-create-on-match

他们提供的例子是:

与ON CREATE和ON MATCH合并 如果需要创建节点,请合并节点并设置属性。

查询。

MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
ON MATCH SET keanu.lastSeen = timestamp()
RETURN keanu.name, keanu.created, keanu.lastSeen

查询创建'keanu'节点,并在创建时设置时间戳。如果'keanu'已经存在,则会设置不同的属性。

所以我修改了我的代码“做同样的事情”:

var query = graphClient.Cypher
            .Merge("(newbid:Bid { ID: {bID} })")
            .OnMatch()
            .Set("newbid = {bid}")
            .OnCreate()
            .Set("newbid = {bid}")
                .WithParams(new
                {
                    bID = bid.ID,
                    bid
                })

            .Merge("(newask:Ask { ID: {aID} })")
            .OnMatch()
            .Set("newask = {ask}")
            .OnCreate()
            .Set("newask = {ask}")
                .WithParams(new
                {
                    aID = ask.ID,
                    ask
                })

            .Merge("(newMarketInfo:MarketInfo { ID: {id}, ASK: {askID}, BID: {bidID} })")
            .OnCreate()
            .Set("newMarketInfo = {mi}")
                .WithParams(new
                {
                    id = mi.ID,
                    bidID = bid.ID,
                    askID = ask.ID,
                    mi
                })
            .Merge("(newask)-[rA:Ask_Input_Data]->(newMarketInfo)")
            .Merge("(newbid)-[rB:Bid_Input_Data]->(newMarketInfo)");
        query.ExecuteWithoutResultsAsync();

然而,节点MarketInfo节点仍然是重复的。我想我现在正走在正确的道路上,但是......我仍然缺少一些东西。

2 个答案:

答案 0 :(得分:2)

所以这就是问题所在,这让我很烦恼......

您无法使用" ID"作为对象的参数。你可以使用" Id"或" id"或" iD"但不是" ID"。一旦我换成使用" Id",该节点再也不会重复了。

答案 1 :(得分:0)

  1. 根据提供的信息,每次运行代码时,"(newMarketInfo:MarketInfo { ID: {id}, ASK: {askID}, BID: {bidID} })"的{​​{1}}值都会

  2. 另一个选项是ID参数值具有更改节点的mi值的值。换句话说,作为示例,可能是您正在合并{ ID: {id}, ASK: {askID}, BID: {bidID} }然后{ ID: {1}, ASK: {2}, BID: {3} },立即设置ON CREATE,将节点的值更改为"newMarketInfo = {mi}"。在这种情况下,合并将始终创建一个新节点,但是当您检查结果时,创建的节点将看起来相同。有道理吗?

  3. 更新

    您添加的照片显示您的{ ID: {2}, ASK: {3}, BID: {4}, exampleValue: {5} }个节点没有MarketInfoASK属性(您要合并的属性)。假设这些属性不应该是BID。这让我觉得我上面的第二个假设解释了发生了什么。要测试这一点,您可以尝试删除

    null

    您的部分查询。在此方案中,查看合并在数据库中保留的节点。节点是否具有.OnCreate().Set("newMarketInfo = {mi}") / ASK属性?如果是,那么你已经找到了问题所在。您还可以查看在此方案中运行查询两次是否添加第二个节点。如果没有,问题肯定是BID条款。