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

Neo4j: Merge duplicating one of three nodes in a query

正如我在另一个 post 上所说的那样,我正在从 SQL 服务器迁移到 Neo4j,所以我正在与学习曲线作斗争。我在搜索 Whosebug 和 google 来回答我的问题方面做得相当好,但我偶然发现了一个奇怪的查询结果,该查询没有意义。

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();
}

我目前正在调试程序,所以这条语句对同一个数据执行了多次。是的,我现在进入数据库并删除所有节点。

创建"Bid"节点和"Ask"节点时,它成功地与现有节点合并,但"MarketInfo"节点正在被复制。

有什么想法吗?

编辑 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' 已经存在,则会设置不同的 属性。

所以我将代码修改为 "do the same":

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 节点仍在复制。我想我现在正朝着正确的方向前进,但是......我仍然缺少一些东西。

  1. 根据提供的信息,听起来 很可能 "(newMarketInfo:MarketInfo { ID: {id}, ASK: {askID}, BID: {bidID} })" 每次 [=48] 都有不同的 ID 值=] 你的代码。

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

更新

您添加的照片显示您的 MarketInfo 节点没有 ASKBID 属性(您要合并的属性)。假设这些属性不应该是 null。这让我认为我上面的第二个假设解释了正在发生的事情。要对此进行测试,您可以尝试消除

.OnCreate().Set("newMarketInfo = {mi}")

您查询的一部分。在这种情况下,请查看您的合并在数据库中持久存在的节点。节点是否具有 ASK / BID 属性?如果是,那么您已经找到问题所在。您还可以查看 运行 在这种情况下查询两次是否会添加第二个节点。如果不是,问题肯定出在 ON CREATE 子句上。

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

您不能使用 "ID" 作为对象的参数。您可以使用 "Id" 或 "id" 或 "iD",但不能使用 "ID"。一旦我切换到使用 "Id",该节点就再也没有被复制过。